"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPromptInitCommand = createPromptInitCommand;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const config_store_1 = require("../../../lib/config/config-store");
const config_layer_resolution_1 = require("../../../lib/config/config-layer-resolution");
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const paths_1 = require("../../../lib/paths");
const prompt_version_evidence_1 = require("../../../lib/prompts/prompt-version-evidence");
const prompt_rendering_evidence_1 = require("../../../lib/prompts/prompt-rendering-evidence");
const prompt_materialization_1 = require("../../../lib/prompts/prompt-materialization");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const global_format_1 = require("../global-format");
const path_utils_1 = require("../prompt/path-utils");
async function createPromptInitCommand() {
    const { Command } = await import("commander");
    const command = new Command("init");
    command
        .description("Materialize one resolved prompt into the matching user-layer path.")
        .requiredOption("--prompt <path>", "Repository-relative prompt path to initialize.")
        .option("--force", "Explicitly allow replacing an existing user-layer prompt with fallback source content.")
        .action((_, commandInstance) => {
        const format = (0, output_1.resolveOutputFormat)((0, global_format_1.getGlobalFormat)(commandInstance));
        if (format === null) {
            throw (0, errors_1.createUsageError)("Output format must be one of: text, json.", [`Received: ${String((0, global_format_1.getGlobalFormat)(commandInstance))}`]);
        }
        const repositoryContext = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const configResult = (0, config_store_1.readResolvedConfig)(repositoryContext);
        const commandOptions = commandInstance.opts();
        const requestedPromptPath = (0, paths_1.parseRepositoryRelativePath)(readRequiredStringOption(commandOptions.prompt, "--prompt")).normalizedPath;
        const promptResolution = (0, config_layer_resolution_1.resolveRequiredPromptReference)({
            repositoryRoot: repositoryContext.root,
            config: configResult.resolved.values,
            requestedPromptPath
        });
        const destinationPromptPath = (0, path_utils_1.toUserLayerPromptPath)(requestedPromptPath, configResult.resolved.values);
        const destinationAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryContext.root, destinationPromptPath);
        const destinationExists = node_fs_1.default.existsSync(destinationAbsolutePath);
        const sourceAttempt = selectPromptInitSource({
            attempts: promptResolution.attempts,
            destinationExists,
            force: commandOptions.force === true
        });
        const sourceAbsolutePath = (0, path_utils_1.resolvePromptSourceAbsolutePath)({
            repositoryRoot: repositoryContext.root,
            resolvedPromptPath: sourceAttempt.promptPath,
            config: configResult.resolved.values,
            source: sourceAttempt.source
        });
        const sourceContent = node_fs_1.default.readFileSync(sourceAbsolutePath, "utf8");
        let outcome;
        let writeOutcome;
        let writeApplied = false;
        let preservedExistingUserPrompt = false;
        let recoveryGuidance = [];
        if (destinationExists) {
            if (commandOptions.force === true && sourceAttempt.promptPath !== destinationPromptPath) {
                applyPromptMaterialization({
                    repositoryRoot: repositoryContext.root,
                    destinationPromptPath,
                    sourcePromptPath: sourceAttempt.promptPath,
                    sourceLayer: requireUpstreamLayer(sourceAttempt.layer),
                    sourceContent
                });
                outcome = "overwritten";
                writeOutcome = "overwrite";
                writeApplied = true;
            }
            else {
                outcome = "preserved";
                writeOutcome = "keep";
                preservedExistingUserPrompt = true;
                recoveryGuidance = [
                    "Compare the existing user prompt with the active source before replacing it.",
                    "Rerun with --force only when replacing the user-layer prompt is intended.",
                    "Use repository history or backups to recover prior prompt content."
                ];
            }
        }
        else {
            applyPromptMaterialization({
                repositoryRoot: repositoryContext.root,
                destinationPromptPath,
                sourcePromptPath: sourceAttempt.promptPath,
                sourceLayer: requireUpstreamLayer(sourceAttempt.layer),
                sourceContent
            });
            outcome = "materialized";
            writeOutcome = "create";
            writeApplied = true;
        }
        const result = {
            requestedPromptPath,
            resolvedPromptPath: promptResolution.resolvedPromptPath,
            sourcePromptPath: sourceAttempt.promptPath,
            destinationPromptPath,
            resolvedLayer: promptResolution.resolvedLayer,
            sourceLayer: sourceAttempt.layer,
            source: sourceAttempt.source,
            activeSource: {
                requestedPromptPath,
                resolvedPromptPath: promptResolution.resolvedPromptPath,
                resolvedLayer: promptResolution.resolvedLayer,
                sourcePromptPath: sourceAttempt.promptPath,
                sourceLayer: sourceAttempt.layer,
                sourceFamily: sourceAttempt.source,
                destinationPromptPath
            },
            fallbackTrace: promptResolution.fallbackTrace,
            outcome,
            writeOutcome,
            writeApplied,
            forced: commandOptions.force === true,
            preservedExistingUserPrompt,
            recoveryGuidance,
            warning: promptResolution.warning,
            promptRenderingEvidence: (0, prompt_rendering_evidence_1.collectPromptRenderingEvidence)({
                repositoryRoot: repositoryContext.root,
                requestedPromptPath,
                resolvedPromptPath: promptResolution.resolvedPromptPath,
                resolvedLayer: promptResolution.resolvedLayer,
                sourceFamily: sourceAttempt.source,
                fallbackTrace: promptResolution.fallbackTrace,
                userLayerDestinationPath: destinationPromptPath,
                promptResolutionWarning: promptResolution.warning,
                promptInstructionsPath: sourceAttempt.promptPath,
                requireAgentEntrypoint: false,
                degradedNoAgent: false
            }),
            promptVersionEvidence: (0, prompt_version_evidence_1.collectPromptVersionEvidence)({
                repositoryRoot: repositoryContext.root,
                promptPath: sourceAttempt.promptPath,
                promptContent: sourceContent,
                manifestPath: node_path_1.default.posix.join(configResult.resolved.values.prompt_user_root, "manifest.json"),
                canonicalPromptPath: destinationPromptPath
            })
        };
        (0, output_1.emitSuccess)({
            command: "prompt init",
            format,
            text: renderPromptInitText(result),
            data: {
                repositoryRoot: repositoryContext.root,
                detectionSource: repositoryContext.detectionSource,
                requestedPromptPath: result.requestedPromptPath,
                resolvedPromptPath: result.resolvedPromptPath,
                sourcePromptPath: result.sourcePromptPath,
                destinationPromptPath: result.destinationPromptPath,
                activeSource: result.activeSource,
                fallbackTrace: result.fallbackTrace,
                promptResolution,
                promptRenderingEvidence: result.promptRenderingEvidence,
                promptVersionEvidence: result.promptVersionEvidence,
                sourceLayer: result.sourceLayer,
                sourceOrigin: result.source,
                outcome: result.outcome,
                writeOutcome: result.writeOutcome,
                writeApplied: result.writeApplied,
                forced: result.forced,
                preservedExistingUserPrompt: result.preservedExistingUserPrompt,
                recoveryGuidance: result.recoveryGuidance
            }
        });
    });
    return command;
}
function readRequiredStringOption(value, flagName) {
    if (typeof value !== "string" || value.trim().length === 0) {
        throw (0, errors_1.createUsageError)(`${flagName} requires a non-empty value.`, [
            `Pass ${flagName} with a repository-relative prompt path.`
        ]);
    }
    return value;
}
function applyPromptMaterialization(options) {
    const mutation = (0, prompt_materialization_1.createPromptMaterializationMutation)({
        repositoryRoot: options.repositoryRoot,
        promptPath: options.destinationPromptPath,
        promptContents: options.sourceContent,
        upstreamPath: options.sourcePromptPath,
        upstreamLayer: options.sourceLayer,
        upstreamContents: options.sourceContent,
        writeOwner: "prompt init"
    });
    (0, prompt_materialization_1.applyPromptMaterializationMutationSync)({
        repositoryRoot: options.repositoryRoot,
        mutation
    });
}
function requireUpstreamLayer(layer) {
    if (layer === "latest" || layer === "packaged-default") {
        return layer;
    }
    throw new Error("Prompt materialization cannot use the user layer as its upstream base.");
}
function selectPromptInitSource(options) {
    if (options.destinationExists && options.force) {
        const preferredFallback = options.attempts.find((attempt) => attempt.layer === "latest" && attempt.found) ?? options.attempts.find((attempt) => attempt.layer === "packaged-default" && attempt.found);
        if (preferredFallback !== undefined) {
            return preferredFallback;
        }
    }
    const resolvedAttempt = options.attempts.find((attempt) => attempt.found);
    if (resolvedAttempt === undefined) {
        throw new Error("Prompt init could not locate a source attempt after successful prompt resolution.");
    }
    return resolvedAttempt;
}
function renderPromptInitText(result) {
    const lines = [
        (0, output_1.renderTerminalHeading)("Prompt Init", "title"),
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Outcome", value: result.outcome },
                { label: "Write outcome", value: result.writeOutcome },
                { label: "Force requested", value: result.forced ? "yes" : "no" },
                { label: "Preserved existing user prompt", value: result.preservedExistingUserPrompt ? "yes" : "no" }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Paths",
            fields: [
                { label: "Requested prompt", value: result.requestedPromptPath },
                { label: "Resolved prompt", value: result.resolvedPromptPath },
                { label: "Source prompt", value: result.sourcePromptPath },
                { label: "Destination", value: result.destinationPromptPath }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Prompt Source",
            fields: [
                { label: "Resolved layer", value: result.resolvedLayer },
                { label: "Source layer", value: `${result.sourceLayer} (${result.source})` },
                {
                    label: "Active source",
                    value: `${result.activeSource.sourcePromptPath} [${result.activeSource.sourceLayer}/${result.activeSource.sourceFamily}]`
                },
                { label: "Fallback trace", value: result.fallbackTrace.length === 0 ? "(none)" : result.fallbackTrace.join("\n") }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Write Boundary",
            lines: [
                result.writeApplied
                    ? (0, output_1.renderTerminalBoundary)({
                        kind: "write-applied",
                        target: result.destinationPromptPath,
                        targetLabel: "Destination"
                    })
                    : result.preservedExistingUserPrompt
                        ? (0, output_1.renderTerminalBoundary)({
                            kind: "force-gated-write",
                            reason: "Existing user-layer prompt was preserved; rerun with --force only when replacement is intended."
                        })
                        : (0, output_1.renderTerminalBoundary)({
                            kind: "mutating-no-op",
                            reason: "Destination already matched the selected prompt state.",
                            target: result.destinationPromptPath,
                            targetLabel: "Destination"
                        })
            ]
        })
    ];
    if (result.recoveryGuidance.length > 0) {
        lines.push("", (0, output_1.renderTerminalCompactList)({
            heading: "Recovery",
            entries: result.recoveryGuidance.map((guidance) => ({ label: guidance }))
        }));
    }
    if (result.warning !== null) {
        lines.push("", (0, output_1.renderTerminalSection)({
            heading: "Warnings",
            lines: [result.warning]
        }));
    }
    lines.push("", (0, output_1.renderTerminalSection)({
        heading: "Prompt Rendering Evidence",
        fields: [
            { label: "Prompt render lanes", value: result.promptRenderingEvidence.visibleLaneOrder.join(" -> ") },
            {
                label: "Agent entrypoint",
                value: `${result.promptRenderingEvidence.agentEntrypointGuidance.path} (${result.promptRenderingEvidence.agentEntrypointGuidance.present ? "present" : "missing"})`
            },
            {
                label: "Agent entrypoint required for this surface",
                value: result.promptRenderingEvidence.agentEntrypointGuidance.requiredForSurface ? "yes" : "no"
            },
            {
                label: "Degraded mode",
                value: result.promptRenderingEvidence.degradedMode.requested ? result.promptRenderingEvidence.degradedMode.explicitFlag : "no"
            },
            { label: "Unresolved token pattern", value: result.promptRenderingEvidence.unresolvedTokenPattern }
        ]
    }), "", (0, output_1.renderTerminalSection)({
        heading: "Version Evidence",
        fields: [
            { label: "Prompt Markdown version", value: renderEvidenceValue(result.promptVersionEvidence.promptMarkdown.promptVersion) },
            { label: "Prompt manifest version", value: renderEvidenceValue(result.promptVersionEvidence.promptManifest.promptManifestVersion) },
            { label: "Prompt shared version", value: renderEvidenceValue(result.promptVersionEvidence.promptManifest.promptVersion) },
            { label: "Prompt entry version", value: renderEvidenceValue(result.promptVersionEvidence.promptManifest.entryVersion) }
        ]
    }));
    if (result.promptVersionEvidence.promptManifest.warning !== null) {
        lines.push("", (0, output_1.renderTerminalSection)({
            heading: "Manifest Warnings",
            lines: [result.promptVersionEvidence.promptManifest.warning]
        }));
    }
    return lines.join("\n");
}
function renderEvidenceValue(value) {
    return value === null ? "(missing)" : String(value);
}
