"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createExplainCommand = createExplainCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const workspace_ignore_1 = require("../../../lib/workspace-ignore");
const global_format_1 = require("../global-format");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
function parseRule(value, decision) {
    if (!value.trim())
        throw (0, errors_1.createUsageError)('Ignore-policy rule patterns must not be empty.');
    return { pattern: value, decision, rationale: 'Explicit invocation override.' };
}
async function createExplainCommand() {
    const { Command } = await import('commander');
    return new Command('explain')
        .description('Explain the canonical read-only ignore-policy decision for a workspace-relative path.')
        .argument('<path>', 'Workspace-relative path to explain.')
        .option('--include <pattern>', 'Add a highest-precedence inclusion override.', (v, a) => [...a, v], [])
        .option('--exclude <pattern>', 'Add a highest-precedence exclusion override.', (v, a) => [...a, v], [])
        .option('--ignore-file <path>', 'Read ignore-file evidence from a workspace-relative file.')
        .action((requestedPath, options, command) => {
        const format = (0, output_1.resolveOutputFormat)((0, global_format_1.getGlobalFormat)(command));
        if (format === null)
            throw (0, errors_1.createUsageError)('Output format must be one of: text, json.');
        const context = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        let ignoreFileRules = [];
        if (options.ignoreFile) {
            const candidate = node_path_1.default.resolve(context.root, options.ignoreFile);
            const relative = node_path_1.default.relative(context.root, candidate);
            if (relative.startsWith('..') || node_path_1.default.isAbsolute(relative))
                throw (0, errors_1.createUsageError)('Ignore file must remain inside the effective workspace.');
            ignoreFileRules = (0, workspace_ignore_1.parseIgnoreFileRules)(node_fs_1.default.readFileSync(candidate, 'utf8'));
        }
        const invocationRules = [
            ...options.exclude.map((v) => parseRule(v, 'exclude')),
            ...options.include.map((v) => parseRule(v, 'include')),
        ];
        const result = (0, workspace_ignore_1.explainIgnorePolicy)((0, workspace_ignore_1.createIgnorePolicy)({ workspaceRoot: context.root, ignoreFileRules, invocationRules }), requestedPath);
        (0, output_1.emitSuccess)({
            command: 'ignore explain',
            format,
            data: result,
            text: [
                `Ignore policy: ${result.policyId}`,
                `Path: ${result.normalizedPath ?? result.requestedPath}`,
                `Decision: ${result.decision}`,
                result.winningRule
                    ? `Winning rule: ${result.winningRule.pattern} (${result.winningRule.sourceKind}: ${result.winningRule.sourceId})`
                    : 'Winning rule: none (included by default)',
                result.containmentFailure
                    ? `Containment failure: ${result.containmentFailure}`
                    : 'Boundary: read-only; no files were changed.',
            ].join('\n'),
        });
    });
}
