"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") });
    });
}
