"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PROMPT_RECONCILIATION_DECISIONS = void 0;
exports.createPromptReconciliationPlan = createPromptReconciliationPlan;
exports.applyPromptReconciliationPlanSync = applyPromptReconciliationPlanSync;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const multi_file_mutation_1 = require("../filesystem/multi-file-mutation");
const paths_1 = require("../paths");
const path_resolution_1 = require("./path-resolution");
const default_assets_1 = require("../workspace-init/default-assets");
const prompt_materialization_1 = require("./prompt-materialization");
const prompt_upgrade_1 = require("./prompt-upgrade");
exports.PROMPT_RECONCILIATION_DECISIONS = ["preserve", "replace"];
function createPromptReconciliationPlan(options) {
    const requestedPromptPath = (0, paths_1.parseRepositoryRelativePath)(options.requestedPromptPath).normalizedPath;
    const promptSuffix = (0, path_resolution_1.resolvePromptSuffix)(requestedPromptPath, options.config);
    const promptPath = node_path_1.default.posix.join(options.config.prompt_user_root, promptSuffix);
    const promptAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, promptPath);
    const userEvidence = (0, multi_file_mutation_1.inspectMutationPathSync)(promptAbsolutePath);
    const stateAbsolutePath = (0, prompt_materialization_1.resolvePromptMaterializationStateAbsolutePath)(options.repositoryRoot);
    const statePathEvidence = (0, multi_file_mutation_1.inspectMutationPathSync)(stateAbsolutePath);
    const stateRead = (0, prompt_materialization_1.readPromptMaterializationStateSync)(options.repositoryRoot);
    const issues = [];
    if (stateRead.status === "malformed") {
        issues.push(stateRead.error);
    }
    if (!userEvidence.exists) {
        issues.push(`User prompt is missing: ${promptPath}`);
    }
    const materializationRecord = stateRead.status === "malformed"
        ? null
        : (0, prompt_materialization_1.findPromptMaterializationRecord)(stateRead.state, promptPath);
    if (materializationRecord === null) {
        issues.push(`Materialization base evidence is missing for '${promptPath}'.`);
    }
    const deliveryMode = stateRead.status === "malformed"
        ? null
        : stateRead.state.latestDelivery?.mode ?? null;
    const upstream = resolveReconciliationUpstream({
        repositoryRoot: options.repositoryRoot,
        config: options.config,
        promptSuffix,
        stateRead,
        issues
    });
    const classification = (0, prompt_materialization_1.classifyPromptDrift)({
        baseSha256: materializationRecord?.baseSha256 ?? null,
        userSha256: userEvidence.contentHash,
        upstreamSha256: upstream.sha256,
        evidenceValid: issues.length === 0
    });
    const allowedDecisions = ["preserve"];
    if (upstream.available
        && userEvidence.exists
        && stateRead.status !== "malformed") {
        allowedDecisions.push("replace");
    }
    const previewHash = (0, prompt_materialization_1.hashPromptEvidence)({
        schemaVersion: 1,
        requestedPromptPath,
        promptPath,
        stateSha256: statePathEvidence.contentHash,
        userSha256: userEvidence.contentHash,
        deliveryMode,
        materializationRecord,
        upstream,
        classification: {
            state: classification.state,
            needsReplacement: classification.needsReplacement
        },
        evidenceIssues: issues
    });
    return {
        requestedPromptPath,
        promptPath,
        deliveryMode,
        materializationRecord,
        upstream,
        classification,
        evidenceIssues: issues,
        allowedDecisions,
        previewHash,
        writeApplied: false
    };
}
function applyPromptReconciliationPlanSync(options) {
    assertReconciliationDecision(options.decision);
    if (!/^[a-f0-9]{64}$/.test(options.previewHash)) {
        throw new TypeError("Prompt reconciliation preview hash must be 64 lowercase hexadecimal characters.");
    }
    const plan = createPromptReconciliationPlan(options);
    if (plan.previewHash !== options.previewHash) {
        throw new Error("Prompt reconciliation preview is stale; rerun preview before apply.");
    }
    if (!plan.allowedDecisions.includes(options.decision)) {
        throw new Error(`Prompt reconciliation decision '${options.decision}' is not allowed with the current evidence.`);
    }
    if (options.decision === "preserve") {
        return {
            plan,
            decision: options.decision,
            writeApplied: false,
            updatedPaths: [],
            mutation: null
        };
    }
    if (plan.upstream.path === null || plan.upstream.layer === null) {
        throw new Error("Prompt reconciliation replacement requires a complete upstream source.");
    }
    const upstreamContents = readReconciliationUpstreamContents({
        repositoryRoot: options.repositoryRoot,
        upstreamPath: plan.upstream.path,
        upstreamLayer: plan.upstream.layer
    });
    if ((0, prompt_materialization_1.hashPromptContent)(upstreamContents) !== plan.upstream.sha256) {
        throw new Error("Prompt reconciliation upstream changed after preview; rerun preview before apply.");
    }
    const materialization = (0, prompt_materialization_1.createPromptMaterializationMutation)({
        repositoryRoot: options.repositoryRoot,
        promptPath: plan.promptPath,
        promptContents: upstreamContents,
        upstreamPath: plan.upstream.path,
        upstreamLayer: plan.upstream.layer,
        upstreamContents,
        writeOwner: "prompt reconcile apply"
    });
    const revalidatedPlan = createPromptReconciliationPlan(options);
    if (revalidatedPlan.previewHash !== options.previewHash) {
        throw new Error("Prompt reconciliation preview became stale before apply; no files were written.");
    }
    const mutation = (0, prompt_materialization_1.applyPromptMaterializationMutationSync)({
        repositoryRoot: options.repositoryRoot,
        mutation: materialization
    });
    const writeApplied = (mutation.receipt?.applied.length ?? 0) > 0;
    return {
        plan,
        decision: options.decision,
        writeApplied,
        updatedPaths: writeApplied
            ? [plan.promptPath, ".day-shift/state/prompt-materializations.json"]
            : [],
        mutation
    };
}
function resolveReconciliationUpstream(options) {
    if (options.stateRead.status === "malformed") {
        return unavailableUpstream();
    }
    const delivery = options.stateRead.state.latestDelivery;
    if (delivery === null) {
        options.issues.push("Latest prompt delivery evidence is missing; run workspace upgrade preview/apply.");
        return unavailableUpstream();
    }
    const verification = (0, prompt_upgrade_1.verifyLatestPromptDelivery)({
        repositoryRoot: options.repositoryRoot,
        config: options.config,
        state: options.stateRead.state
    });
    if (!verification.complete) {
        options.issues.push(verification.reason ?? "Latest prompt delivery evidence is incomplete.");
        return unavailableUpstream();
    }
    if (delivery.mode === "materialized") {
        const latestPath = node_path_1.default.posix.join(options.config.prompt_latest_root, options.promptSuffix);
        const delivered = delivery.prompts.find((prompt) => prompt.path === latestPath);
        if (delivered === undefined) {
            options.issues.push(`Latest delivery evidence does not contain '${latestPath}'.`);
            return unavailableUpstream();
        }
        return {
            path: latestPath,
            layer: "latest",
            sha256: delivered.sha256,
            available: true
        };
    }
    const packaged = (0, default_assets_1.getDefaultPackagedPromptMarkdownAssets)()
        .find((asset) => asset.promptSuffix === options.promptSuffix);
    if (packaged === undefined) {
        options.issues.push(`Packaged prompt is missing for '${options.promptSuffix}'.`);
        return unavailableUpstream();
    }
    return {
        path: packaged.path,
        layer: "packaged-default",
        sha256: (0, prompt_materialization_1.hashPromptContent)(packaged.contents),
        available: true
    };
}
function readReconciliationUpstreamContents(options) {
    if (options.upstreamLayer === "latest") {
        return node_fs_1.default.readFileSync((0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, options.upstreamPath), "utf8");
    }
    const packaged = (0, default_assets_1.getDefaultPackagedPromptMarkdownAssets)()
        .find((asset) => asset.path === options.upstreamPath);
    if (packaged === undefined) {
        throw new Error(`Packaged prompt source is missing: ${options.upstreamPath}`);
    }
    return packaged.contents;
}
function unavailableUpstream() {
    return { path: null, layer: null, sha256: null, available: false };
}
function assertReconciliationDecision(decision) {
    if (!exports.PROMPT_RECONCILIATION_DECISIONS.includes(decision)) {
        throw new TypeError(`Unsupported prompt reconciliation decision '${decision}'.`);
    }
}
