"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createValidationRollupCommand = createValidationRollupCommand;
const node_fs_1 = __importDefault(require("node:fs"));
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const doctor_1 = require("../../../lib/doctor");
const paths_1 = require("../../../lib/paths");
const global_format_1 = require("../global-format");
const ROLLUP_NO_WRITE_BOUNDARY = "Reports rollup evidence only; must not repair links, synchronize metadata, write checkpoints, mutate status, or generate planning artifacts.";
async function createValidationRollupCommand() {
    const { Command } = await import("commander");
    const command = new Command("rollup");
    command
        .description("Run a read-only, local-only validation rollup over supported planning evidence lanes.")
        .option("--scope <scope>", "Validation rollup scope. Currently only 'planning' is supported.", "planning")
        .option("--format <format>", "Validation rollup output format. Accepted values: text, json.")
        .option("--artifact <path>", "Optional repository-relative planning artifact path to focus future rollup evidence.")
        .action((_, commandInstance) => {
        const options = commandInstance.opts();
        const requestedFormat = options.format ?? (0, global_format_1.getGlobalFormat)(commandInstance);
        const format = (0, output_1.resolveOutputFormat)(requestedFormat);
        if (format === null) {
            throw (0, errors_1.createUnsupportedOutputFormatError)({
                received: requestedFormat,
                commandBoundary: "validation rollup command output format"
            });
        }
        if (options.scope !== "planning") {
            throw (0, errors_1.createUsageError)("Validation rollup currently supports only the 'planning' scope.", [`Received: ${String(options.scope)}`]);
        }
        const artifactPath = normalizeOptionalArtifactPath(options.artifact);
        assertFocusedArtifactExists(commandInstance, artifactPath);
        const report = (0, doctor_1.runPlanningValidationSmoke)({
            artifactPath: artifactPath ?? undefined
        });
        const findings = normalizeValidationRollupFindings(report.findings);
        if (findings.some((finding) => finding.severity === "error")) {
            getRootCommand(commandInstance).runtimeExitCode = errors_1.RuntimeExitCode.ERROR;
        }
        (0, output_1.emitSuccess)({
            command: "validation rollup",
            format,
            text: renderValidationRollupReport({ ...report, findings }, artifactPath),
            data: {
                repositoryRoot: report.repositoryRoot,
                detectionSource: report.detectionSource,
                scope: "planning",
                artifact: artifactPath,
                planningRootPath: report.planningRootPath,
                readOnly: true,
                localOnly: true,
                writeCapable: false,
                outputContracts: (0, output_1.getValidationCommandOutputContracts)(),
                readOnlyFailureContract: (0, output_1.getValidationReadOnlyFailureContract)(),
                evidenceSourceInventory: report.evidenceSourceInventory,
                specializedReviewBoundaries: report.specializedReviewBoundaries,
                aggregationContract: report.aggregationContract,
                checks: report.checks,
                inventoryFindings: report.inventoryFindings,
                crossArtifactAlignment: report.crossArtifactAlignment,
                baseline: report.baseline,
                gaps: report.gaps,
                nextActions: report.nextActions,
                nextAction: report.nextAction,
                summary: report.summary,
                readinessStatus: report.readinessStatus,
                implementationState: "existing",
                noWriteBoundary: ROLLUP_NO_WRITE_BOUNDARY
            },
            findings
        });
    });
    return command;
}
function normalizeValidationRollupFindings(findings) {
    return findings.map((finding) => (0, output_1.createValidationFinding)({
        ...finding,
        id: finding.id ?? finding.code,
        code: finding.code ?? finding.id,
        summary: finding.summary ?? finding.message,
        message: finding.message ?? finding.summary,
        detail: finding.detail ?? finding.message ?? finding.summary,
        level: finding.level ?? finding.severity,
        severity: finding.severity ?? finding.level,
        affectedPaths: finding.affectedPaths ?? (finding.path === undefined
            ? []
            : [
                (0, output_1.createValidationAffectedPath)({
                    role: "finding-location",
                    path: finding.path,
                    description: finding.message
                })
            ]),
        artifacts: finding.artifacts ?? [],
        recovery: finding.recovery ?? "Review the validation rollup evidence before running any write-capable follow-up.",
        evidence: finding.evidence ?? (0, output_1.createValidationCommandEvidence)({
            category: "validation-rollup",
            details: {
                source: "validation-rollup",
                noWriteRequired: true
            }
        })
    }));
}
function renderValidationRollupReport(report, artifactPath) {
    const suppressedBaselineCount = report.baseline.suppressedFindings
        + report.baseline.suppressedInventoryFindings
        + report.baseline.suppressedGaps;
    const lines = [
        (0, output_1.renderTerminalHeading)("Day Shift validation rollup", "title").trimEnd(),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Command", value: "validation rollup" },
                { label: "Repository root", value: report.repositoryRoot },
                { label: "Detection source", value: report.detectionSource },
                { label: "Scope", value: report.scope },
                { label: "Artifact", value: artifactPath ?? "(none)" },
                { label: "Mode", value: "read-only, local-only" },
                { label: "Write capable", value: "no" },
                { label: "Planning root", value: report.planningRootPath },
                { label: "Readiness status", value: report.readinessStatus },
                {
                    label: "Checks",
                    value: `${report.summary.totalChecks} total, ${report.summary.passed} passed, ${report.summary.informational} informational, ${report.summary.warnings} warnings, ${report.summary.errors} errors`
                },
                { label: "Source lanes", value: report.aggregationContract.sourceLaneFields.join(", ") },
                { label: "Findings", value: report.findings.length },
                { label: "Inventory findings", value: report.inventoryFindings.length },
                { label: "Planning gaps", value: report.gaps.length },
                { label: "Forward-only baseline", value: report.baseline.present ? `${report.baseline.path} (${suppressedBaselineCount} suppressed)` : "none" },
                { label: "Baseline read evidence only", value: report.baseline.present ? "existing checkpoint was read" : "no checkpoint was read" },
                { label: "No-write boundary", value: ROLLUP_NO_WRITE_BOUNDARY }
            ],
            lines: [(0, output_1.renderTerminalBoundary)({ kind: "read-only" })]
        }),
        "",
        (0, output_1.renderTerminalCompactList)({
            heading: "Check results:",
            entries: report.checks.map((check) => ({
                label: `[${check.status}] ${check.id}`,
                lines: [check.message]
            }))
        })
    ];
    lines.push("", (0, output_1.renderValidationFindingsText)(report.findings, "Structured findings"));
    lines.push("", "Inventory findings:");
    if (report.inventoryFindings.length === 0) {
        lines.push("- (none)");
    }
    else {
        for (const finding of report.inventoryFindings) {
            lines.push(`- ${finding}`);
        }
    }
    lines.push("", "Planning gaps:");
    if (report.gaps.length === 0) {
        lines.push("- (none)");
    }
    else {
        for (const gap of report.gaps) {
            lines.push(`- [${gap.code}] ${gap.message}`);
        }
    }
    lines.push("", "Cross-artifact alignment:");
    lines.push(`- selected family: ${report.crossArtifactAlignment.selectedArtifactFamily}`, `- surface mode: ${report.crossArtifactAlignment.surfaceMode}`, `- no-write: ${report.crossArtifactAlignment.noWrite ? "yes" : "no"}`, `- findings taxonomy: ${report.crossArtifactAlignment.findingsTaxonomy}`);
    for (const lane of report.crossArtifactAlignment.lanes) {
        lines.push(`- [${lane.status}] ${lane.id}: ${lane.findings.length} finding${lane.findings.length === 1 ? "" : "s"}`);
    }
    lines.push("", "Evidence-source inventory:");
    for (const source of report.evidenceSourceInventory) {
        lines.push(`- ${source.id}: ${source.evidenceShapes.join(", ")} (${source.producer.command ?? source.producer.functionName ?? source.producer.path})`);
    }
    lines.push("", "Specialized review boundaries:");
    for (const boundary of report.specializedReviewBoundaries) {
        lines.push(`- ${boundary.id}: ${boundary.command} (${boundary.rollupExecution})`);
    }
    lines.push("", "Aggregation contract:");
    for (const lane of report.aggregationContract.lanes) {
        lines.push(`- ${lane.id}: ${String(lane.reportField)} from ${lane.sourceEvidence}`);
    }
    lines.push(`- baseline policy: ${report.aggregationContract.baselinePolicy}`, `- next-action policy: ${report.aggregationContract.nextActionPolicy}`, `- aggregation no-write boundary: ${report.aggregationContract.noWriteBoundary}`);
    lines.push("", "Next actions:");
    if (report.nextActions.length === 0) {
        lines.push("- (none)");
    }
    else {
        for (const action of report.nextActions) {
            lines.push(`- ${action}`);
        }
    }
    if (report.nextAction !== null) {
        lines.push("", "Artifact guidance:", `- ${report.nextAction.command ?? report.nextAction.recommendation}`);
    }
    return lines.join("\n");
}
function normalizeOptionalArtifactPath(input) {
    if (input === undefined || input === null || input === "") {
        return null;
    }
    if (typeof input !== "string") {
        throw (0, errors_1.createUsageError)("Validation rollup artifact path must be a repository-relative path.", [`Received: ${String(input)}`]);
    }
    try {
        return (0, paths_1.parseRepositoryRelativePath)(input).normalizedPath;
    }
    catch (error) {
        if (error instanceof RangeError) {
            throw (0, errors_1.createUsageError)("Validation rollup artifact path must be a repository-relative path.", [error.message]);
        }
        throw error;
    }
}
function assertFocusedArtifactExists(commandInstance, artifactPath) {
    if (artifactPath === null) {
        return;
    }
    const repositoryRoot = getRootCommand(commandInstance).configRepositoryContext?.root;
    if (typeof repositoryRoot !== "string" || repositoryRoot.trim() === "") {
        return;
    }
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, artifactPath);
    if (node_fs_1.default.existsSync(absolutePath)) {
        return;
    }
    throw new errors_1.RuntimeError({
        message: "Validation rollup artifact evidence is missing.",
        code: "VALIDATION_ROLLUP_ARTIFACT_MISSING",
        exitCode: errors_1.RuntimeExitCode.ERROR,
        details: [`No local artifact exists at: ${artifactPath}`],
        findings: [
            {
                id: "VALIDATION_ROLLUP_ARTIFACT_MISSING",
                code: "VALIDATION_ROLLUP_ARTIFACT_MISSING",
                summary: "Validation rollup artifact evidence is missing.",
                message: "Validation rollup artifact evidence is missing.",
                level: "error",
                severity: "error",
                path: artifactPath,
                recovery: "Provide an existing repository-relative planning artifact path or rerun without --artifact for repo-wide rollup evidence.",
                evidence: {
                    category: "validation-rollup",
                    details: {
                        blockingReason: "invalid-command-input",
                        noWriteRequired: true
                    }
                }
            }
        ]
    });
}
function getRootCommand(commandInstance) {
    let current = commandInstance;
    while (current?.parent != null) {
        current = current.parent;
    }
    return current ?? commandInstance;
}
