"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CONTRACT_REVISION_IMPACT_BUDGET_DEFAULTS = void 0;
exports.resolveContractRevisionImpactBudget = resolveContractRevisionImpactBudget;
exports.resolveConfigValuesAndSources = resolveConfigValuesAndSources;
exports.resolvePromptReference = resolvePromptReference;
exports.resolveRequiredPromptReference = resolveRequiredPromptReference;
exports.renderPromptResolutionSummary = renderPromptResolutionSummary;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../errors");
const path_resolution_1 = require("../prompts/path-resolution");
const default_assets_1 = require("../workspace-init/default-assets");
exports.CONTRACT_REVISION_IMPACT_BUDGET_DEFAULTS = Object.freeze({
    max_invalidated_entries: 100,
    max_evidence_bytes: 10 * 1024 * 1024
});
function resolveContractRevisionImpactBudget(options) {
    const repositoryBudget = options.repositoryConfig.lifecycle
        ?.contract_revision?.impact_budget;
    const selectedProject = options.projectContext.projectId === null
        ? null
        : options.projectContext.projects.find((project) => project.id === options.projectContext.projectId) ?? null;
    const projectBudget = selectedProject?.contractRevisionImpactBudget ?? undefined;
    return {
        schemaVersion: 1,
        thresholds: {
            maxInvalidatedEntries: resolveImpactBudgetThreshold({
                key: "max_invalidated_entries",
                defaultValue: exports.CONTRACT_REVISION_IMPACT_BUDGET_DEFAULTS.max_invalidated_entries,
                repositoryBudget,
                projectBudget,
                explicitBudget: options.explicit,
                repositoryConfigPath: options.repositoryConfigPath,
                projectId: selectedProject?.id
            }),
            maxEvidenceBytes: resolveImpactBudgetThreshold({
                key: "max_evidence_bytes",
                defaultValue: exports.CONTRACT_REVISION_IMPACT_BUDGET_DEFAULTS.max_evidence_bytes,
                repositoryBudget,
                projectBudget,
                explicitBudget: options.explicit,
                repositoryConfigPath: options.repositoryConfigPath,
                projectId: selectedProject?.id
            })
        },
        precedence: ["defaults", "repository", "project", "explicit"]
    };
}
function resolveImpactBudgetThreshold(options) {
    const explicitValue = options.explicitBudget?.[options.key];
    if (explicitValue !== undefined) {
        return {
            key: options.key,
            value: explicitValue,
            sourceKind: "explicit",
            sourceDescription: "Resolved from the explicit revise-contract invocation."
        };
    }
    const projectValue = options.projectBudget?.[options.key];
    if (projectValue !== undefined) {
        return {
            key: options.key,
            value: projectValue,
            sourceKind: "project",
            sourcePath: options.repositoryConfigPath,
            projectId: options.projectId,
            sourceDescription: `Resolved from project '${options.projectId ?? "unknown"}' in .day-shift/config.toml.`
        };
    }
    const repositoryValue = options.repositoryBudget?.[options.key];
    if (repositoryValue !== undefined) {
        return {
            key: options.key,
            value: repositoryValue,
            sourceKind: "repository",
            sourcePath: options.repositoryConfigPath,
            sourceDescription: "Resolved from .day-shift/config.toml."
        };
    }
    return {
        key: options.key,
        value: options.defaultValue,
        sourceKind: "defaults",
        sourceDescription: "Resolved from built-in contract-revision impact-budget defaults."
    };
}
function resolveConfigValuesAndSources(options) {
    const values = {
        planning_root: resolveRepositoryValue("planning_root", options.repositoryConfig, options.defaults),
        spec_root: resolveRepositoryValue("spec_root", options.repositoryConfig, options.defaults),
        spec_index: resolveRepositoryValue("spec_index", options.repositoryConfig, options.defaults),
        agent_entrypoint: resolveRepositoryValue("agent_entrypoint", options.repositoryConfig, options.defaults),
        default_readiness: resolveRepositoryValue("default_readiness", options.repositoryConfig, options.defaults),
        config_schema_version: resolveRepositoryValue("config_schema_version", options.repositoryConfig, options.defaults),
        spec_index_schema_version: resolveRepositoryValue("spec_index_schema_version", options.repositoryConfig, options.defaults),
        template_version: resolveRepositoryValue("template_version", options.repositoryConfig, options.defaults),
        prompt_version: resolveRepositoryValue("prompt_version", options.repositoryConfig, options.defaults),
        prompt_root: resolveRepositoryValue("prompt_root", options.repositoryConfig, options.defaults),
        prompt_latest_root: resolveRepositoryValue("prompt_latest_root", options.repositoryConfig, options.defaults),
        prompt_user_root: resolveRepositoryValue("prompt_user_root", options.repositoryConfig, options.defaults),
        cli_command: resolveRepositoryValue("cli_command", options.repositoryConfig, options.defaults),
        cli_resolution: resolveRepositoryValue("cli_resolution", options.repositoryConfig, options.defaults),
        cli_verified: resolveRepositoryValue("cli_verified", options.repositoryConfig, options.defaults),
        cli_verified_via: resolveRepositoryValue("cli_verified_via", options.repositoryConfig, options.defaults),
        monorepo_projects: resolveRepositoryValue("monorepo_projects", options.repositoryConfig, options.defaults),
        version: options.localConfig.version ?? options.repositoryConfig.version,
        editor: options.localConfig.editor
    };
    return {
        values,
        sources: {
            planning_root: resolveRepositorySource("planning_root", options.repositoryConfig),
            spec_root: resolveRepositorySource("spec_root", options.repositoryConfig),
            spec_index: resolveRepositorySource("spec_index", options.repositoryConfig),
            agent_entrypoint: resolveRepositorySource("agent_entrypoint", options.repositoryConfig),
            default_readiness: resolveRepositorySource("default_readiness", options.repositoryConfig),
            config_schema_version: resolveRepositorySource("config_schema_version", options.repositoryConfig),
            spec_index_schema_version: resolveRepositorySource("spec_index_schema_version", options.repositoryConfig),
            template_version: resolveRepositorySource("template_version", options.repositoryConfig),
            prompt_version: resolveRepositorySource("prompt_version", options.repositoryConfig),
            prompt_root: resolveRepositorySource("prompt_root", options.repositoryConfig),
            prompt_latest_root: resolveRepositorySource("prompt_latest_root", options.repositoryConfig),
            prompt_user_root: resolveRepositorySource("prompt_user_root", options.repositoryConfig),
            cli_command: resolveRepositorySource("cli_command", options.repositoryConfig),
            cli_resolution: resolveRepositorySource("cli_resolution", options.repositoryConfig),
            cli_verified: resolveRepositorySource("cli_verified", options.repositoryConfig),
            cli_verified_via: resolveRepositorySource("cli_verified_via", options.repositoryConfig),
            monorepo_projects: resolveRepositorySource("monorepo_projects", options.repositoryConfig),
            version: options.localConfig.version === undefined
                ? resolveRepositorySource("version", options.repositoryConfig)
                : "local",
            editor: options.localConfig.editor === undefined ? "defaults" : "local"
        }
    };
}
function resolveRepositoryValue(key, repositoryConfig, defaults) {
    const configuredValue = repositoryConfig[key];
    if (configuredValue !== undefined) {
        return configuredValue;
    }
    return defaults[key];
}
function resolveRepositorySource(key, repositoryConfig) {
    return repositoryConfig[key] === undefined ? "defaults" : "repository";
}
function resolvePromptReference(options) {
    const requestedPromptPath = options.requestedPromptPath.replace(/\\/g, "/");
    const promptSuffix = (0, path_resolution_1.resolvePromptSuffix)(requestedPromptPath, options.config);
    const packagedDefaultPromptPath = node_path_1.default.posix.join(options.config.prompt_user_root, promptSuffix);
    const packageRoot = (0, default_assets_1.resolvePackageRootFromWorkspaceInitModuleDirectory)(node_path_1.default.resolve(__dirname, "..", "workspace-init"));
    const attempts = [
        createPromptResolutionAttempt({
            repositoryRoot: options.repositoryRoot,
            config: options.config,
            promptPath: node_path_1.default.posix.join(options.config.prompt_user_root, promptSuffix),
            layer: "user",
            source: "workspace"
        }),
        createPromptResolutionAttempt({
            repositoryRoot: options.repositoryRoot,
            config: options.config,
            promptPath: node_path_1.default.posix.join(options.config.prompt_latest_root, promptSuffix),
            layer: "latest",
            source: "workspace"
        }),
        createPromptResolutionAttempt({
            repositoryRoot: packageRoot,
            config: options.config,
            promptPath: packagedDefaultPromptPath,
            layer: "packaged-default",
            source: "package"
        })
    ];
    const resolvedAttempt = attempts.find((attempt) => attempt.found) ?? null;
    if (resolvedAttempt === null) {
        const attemptedPaths = attempts.map((attempt) => `${attempt.layer}: ${attempt.promptPath}`);
        throw new Error([
            `Prompt '${requestedPromptPath}' is missing from every declared prompt layer.`,
            ...attemptedPaths
        ].join("\n"));
    }
    const fallbackTrace = attempts
        .filter((attempt) => attempt.layer !== resolvedAttempt.layer)
        .filter((attempt) => {
        if (resolvedAttempt.layer === "user") {
            return false;
        }
        if (resolvedAttempt.layer === "latest") {
            return attempt.layer === "user";
        }
        return attempt.layer === "user" || attempt.layer === "latest";
    })
        .map((attempt) => `${attempt.layer}: ${attempt.promptPath}`);
    return {
        requestedPromptPath,
        resolvedLayer: resolvedAttempt.layer,
        resolvedPromptPath: resolvedAttempt.promptPath,
        source: resolvedAttempt.source,
        attempts,
        fallbackTrace,
        warning: renderPromptResolutionWarning(resolvedAttempt.layer, fallbackTrace)
    };
}
function resolveRequiredPromptReference(options) {
    try {
        return resolvePromptReference(options);
    }
    catch (error) {
        const details = error instanceof Error
            ? error.message.split("\n")
            : ["Prompt resolution failed for an unknown reason."];
        throw (0, errors_1.createInvalidConfigError)(`Prompt '${options.requestedPromptPath}' is unavailable across the declared user, latest, and packaged-default layers.`, details);
    }
}
function renderPromptResolutionSummary(promptResolution) {
    if (promptResolution === null) {
        return "(none)";
    }
    const layerSummary = `${promptResolution.resolvedLayer} (${promptResolution.source})`;
    if (promptResolution.warning === null) {
        return layerSummary;
    }
    return `${layerSummary}; ${promptResolution.warning}`;
}
function createPromptResolutionAttempt(options) {
    const absolutePath = (0, path_resolution_1.resolveWorkspacePromptAbsolutePath)({
        repositoryRoot: options.repositoryRoot,
        promptPath: options.promptPath,
        config: options.config
    });
    return {
        layer: options.layer,
        promptPath: options.promptPath,
        found: node_fs_1.default.existsSync(absolutePath),
        source: options.source
    };
}
function renderPromptResolutionWarning(resolvedLayer, fallbackTrace) {
    if (resolvedLayer === "user") {
        return null;
    }
    if (resolvedLayer === "latest") {
        return `User-layer prompt missing; fell back to latest after checking ${fallbackTrace.join(", ")}.`;
    }
    return `Workspace prompt layers missing; fell back to packaged default after checking ${fallbackTrace.join(", ")}.`;
}
