"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createConfigCommand = createConfigCommand;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const global_format_1 = require("../global-format");
const config_store_1 = require("../../../lib/config/config-store");
const cli_constants_1 = require("../../../lib/config/cli-constants");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
function getRepositoryContext() {
    return (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
}
function getConfigCommandFormat(commandInstance) {
    return commandInstance.optsWithGlobals().format ?? (0, global_format_1.getGlobalFormat)(commandInstance);
}
async function createConfigCommand() {
    const { Command } = await import('commander');
    const command = new Command('config');
    command.description('Read or write layered Day Shift configuration.');
    command
        .command('get [selector]')
        .description('Show the resolved configuration values.')
        .option('--project <id>', 'Resolve configuration for one declared monorepo project.')
        .addHelpText('after', `\n${cli_constants_1.CLI_CONFIG_GET_SELECTOR_HELP}\n`)
        .action((selector, _, commandInstance) => {
        const requestedFormat = getConfigCommandFormat(commandInstance);
        const format = (0, output_1.resolveOutputFormat)(requestedFormat);
        if (format === null) {
            throw (0, errors_1.createUsageError)('Output format must be one of: text, json.', [`Received: ${String(requestedFormat)}`]);
        }
        const commandOptions = commandInstance.opts();
        const result = (0, config_store_1.readResolvedConfig)(getRepositoryContext(), {
            projectId: commandOptions.project,
            currentDirectory: process.cwd(),
        });
        const selection = selector === undefined
            ? undefined
            : (0, config_store_1.resolveConfigGetSelection)({
                resolvedConfig: result.resolved,
                selector,
            });
        const data = {
            values: result.resolved.values,
            sources: result.resolved.sources,
            derived: result.resolved.derived,
            projectContext: result.resolved.projectContext,
            resolvedEntries: result.resolved.resolvedEntries,
            ...(selection === undefined
                ? {}
                : {
                    selection: {
                        selector: selection.selector,
                        kind: selection.kind,
                        selectedEntryKeys: selection.entryKeys,
                        selectedEntries: selection.entries,
                    },
                }),
        };
        (0, output_1.emitSuccess)({
            command: 'config get',
            format,
            text: (0, config_store_1.createConfigGetText)(result, selection),
            data,
        });
    });
    command
        .command('inventory')
        .description('List catalog-backed configuration inventory without writing files.')
        .option('--license-file <path>', 'Use a license file for this inventory run without writing config.')
        .option('--project <id>', 'Resolve inventory for one declared monorepo project.')
        .action((_, commandInstance) => {
        const requestedFormat = getConfigCommandFormat(commandInstance);
        const format = (0, output_1.resolveOutputFormat)(requestedFormat);
        if (format === null) {
            throw (0, errors_1.createUsageError)('Output format must be one of: text, json.', [`Received: ${String(requestedFormat)}`]);
        }
        const commandOptions = commandInstance.opts();
        const result = (0, config_store_1.readResolvedConfig)(getRepositoryContext(), {
            includeLicenseProvenance: true,
            licenseFile: commandOptions.licenseFile,
            projectId: commandOptions.project,
            currentDirectory: process.cwd(),
        });
        const inventory = (0, config_store_1.createConfigInventory)(result);
        (0, output_1.emitSuccess)({
            command: 'config inventory',
            format,
            text: (0, config_store_1.createConfigInventoryText)(inventory),
            data: {
                ...inventory,
                projectContext: result.resolved.projectContext,
            },
        });
    });
    command
        .command('set <key> <value>')
        .description('Set a writable configuration value.')
        .addHelpText('after', `\n${cli_constants_1.CLI_CONFIG_SET_KEY_HELP}\n`)
        .action((key, value, _, commandInstance) => {
        const requestedFormat = getConfigCommandFormat(commandInstance);
        const format = (0, output_1.resolveOutputFormat)(requestedFormat);
        if (format === null) {
            throw (0, errors_1.createUsageError)('Output format must be one of: text, json.', [`Received: ${String(requestedFormat)}`]);
        }
        const result = (0, config_store_1.writeConfigValue)({
            repositoryContext: getRepositoryContext(),
            key,
            value,
        });
        node_fs_1.default.mkdirSync(node_path_1.default.dirname(result.filePath), { recursive: true });
        node_fs_1.default.writeFileSync(result.filePath, result.contents, 'utf8');
        (0, output_1.emitSuccess)({
            command: 'config set',
            format,
            text: (0, config_store_1.createConfigSetText)(result),
            data: {
                key: result.key,
                filePath: result.filePath,
                targetLayer: result.targetLayer,
                targetRelativePath: result.targetRelativePath,
                acceptedValue: result.acceptedValue,
                displayValue: result.displayValue,
                preservationStrategy: result.preservationStrategy,
                value: result.displayValue,
            },
        });
    });
    return command;
}
