"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseStructuralPressureState = parseStructuralPressureState;
const errors_1 = require("../../errors");
const paths_1 = require("../../paths");
const planning_document_utils_1 = require("../planning-document-utils");
const contracts_1 = require("./contracts");
const delta_evidence_1 = require("./delta-evidence");
function parseStructuralPressureState(text, filePath) {
    let parsed;
    try {
        parsed = JSON.parse(text);
    }
    catch (error) {
        throw new errors_1.RuntimeError({
            message: "Structural-pressure report failed because the derived state file is not valid JSON.",
            code: "STRUCTURAL_PRESSURE_STATE_INVALID",
            exitCode: errors_1.RuntimeExitCode.ERROR,
            details: [
                `${filePath}: ${error instanceof Error ? error.message : "Could not parse JSON."}`
            ]
        });
    }
    if (!isRecord(parsed)) {
        throw invalidStateError(filePath, "Top-level JSON value must be an object.");
    }
    if (parsed.schema_version !== 1) {
        throw invalidStateError(filePath, "schema_version must equal 1.");
    }
    if (!isRecord(parsed.source)) {
        throw invalidStateError(filePath, "source must be an object.");
    }
    if (!Array.isArray(parsed.entries)) {
        throw invalidStateError(filePath, "entries must be an array.");
    }
    const milestoneReconciliation = requireStringField(parsed.source, "milestone_reconciliation", filePath);
    const milestoneOverview = requireStringField(parsed.source, "milestone_overview", filePath);
    const syncedAt = requireStringField(parsed, "synced_at", filePath);
    const entries = parsed.entries.map((entry, index) => {
        if (!isRecord(entry)) {
            throw invalidStateError(filePath, `entries[${index}] must be an object.`);
        }
        const normalizedPath = (0, paths_1.parseRepositoryRelativePath)(requireStringField(entry, "path", filePath, `entries[${index}]`)).normalizedPath;
        const status = requireEnumField(entry, "status", contracts_1.STRUCTURAL_PRESSURE_STATUSES, filePath, `entries[${index}]`);
        const severity = requireEnumField(entry, "severity", contracts_1.STRUCTURAL_PRESSURE_SEVERITIES, filePath, `entries[${index}]`);
        const summary = requireStringField(entry, "summary", filePath, `entries[${index}]`).trim();
        const evidencePaths = normalizeEvidencePaths(entry.evidence_paths, filePath, `entries[${index}]`);
        const sourceMilestoneReconciliation = requireStringField(entry, "source_milestone_reconciliation", filePath, `entries[${index}]`);
        const sourceMilestoneOverview = requireStringField(entry, "source_milestone_overview", filePath, `entries[${index}]`);
        const structuralDelta = (0, delta_evidence_1.normalizeStructuralPressureDeltaEvidence)(entry.structural_delta, normalizedPath, filePath, `entries[${index}]`, (detail) => invalidStateError(filePath, detail));
        return {
            path: normalizedPath,
            status,
            severity,
            summary,
            evidence_paths: evidencePaths,
            source_milestone_reconciliation: sourceMilestoneReconciliation,
            source_milestone_overview: sourceMilestoneOverview,
            ...(structuralDelta === undefined ? {} : { structural_delta: structuralDelta })
        };
    });
    return {
        schema_version: 1,
        synced_at: syncedAt,
        source: {
            milestone_reconciliation: milestoneReconciliation,
            milestone_overview: milestoneOverview
        },
        entries
    };
}
function requireStringField(input, key, filePath, context = "state") {
    const value = input[key];
    if (typeof value !== "string" || value.trim().length === 0) {
        throw invalidStateError(filePath, `${context}.${key} must be a non-empty string.`);
    }
    return value;
}
function requireEnumField(input, key, values, filePath, context = "state") {
    const value = requireStringField(input, key, filePath, context);
    if (!values.includes(value)) {
        throw invalidStateError(filePath, `${context}.${key} must be one of: ${values.join(", ")}.`);
    }
    return value;
}
function normalizeEvidencePaths(value, filePath, context) {
    if (value === undefined) {
        return [];
    }
    if (!Array.isArray(value)) {
        throw invalidStateError(filePath, `${context}.evidence_paths must be an array when present.`);
    }
    return value.map((entry, index) => {
        if (typeof entry !== "string" || entry.trim().length === 0) {
            throw invalidStateError(filePath, `${context}.evidence_paths[${index}] must be a non-empty string.`);
        }
        return (0, planning_document_utils_1.toRepositoryLikePath)((0, paths_1.parseRepositoryRelativePath)(entry).normalizedPath);
    });
}
function invalidStateError(filePath, detail) {
    return new errors_1.RuntimeError({
        message: "Structural-pressure report failed because the derived state file is malformed.",
        code: "STRUCTURAL_PRESSURE_STATE_INVALID",
        exitCode: errors_1.RuntimeExitCode.ERROR,
        details: [`${filePath}: ${detail}`]
    });
}
function isRecord(value) {
    return typeof value === "object" && value !== null;
}
