"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateSpecRegistryAddInput = validateSpecRegistryAddInput;
const schema_1 = require("./schema");
const read_helpers_1 = require("./read-helpers");
const types_1 = require("./types");
const cli_constants_1 = require("../config/cli-constants");
const EMERGENT_IMPLEMENTATION_ORDER = "00";
const EMERGENT_SPEC_PATH_PATTERN = /^\.day-shift\/specs\/00-emergent\/00-\d{4}-\d{2}-\d{2}-[a-z0-9]+(?:-[a-z0-9]+)*\.md$/;
function validateSpecRegistryAddInput(input) {
    const candidate = readRecord(input.proposedEntry, "Spec add proposal");
    const requiredFields = String(candidate.status ?? "").trim().toLowerCase() === "draft"
        ? types_1.SPEC_INDEX_ENTRY_REQUIRED_FIELDS
        : [...types_1.SPEC_INDEX_ENTRY_REQUIRED_FIELDS, ...types_1.SPEC_INDEX_ENTRY_ROUTED_REQUIRED_FIELDS];
    const missingFields = requiredFields.filter((field) => !(0, read_helpers_1.hasRequiredValue)(candidate[field]));
    if (missingFields.length > 0) {
        return {
            ok: false,
            findings: [
                createFinding("SPEC_ADD_MISSING_REQUIRED_METADATA", `Spec add input is missing required metadata: ${(0, read_helpers_1.formatFieldList)(missingFields)}.`, "error")
            ]
        };
    }
    let parsedEntry;
    try {
        parsedEntry = (0, schema_1.parseSpecIndexEntry)(candidate);
    }
    catch (error) {
        return {
            ok: false,
            findings: [
                createFinding("SPEC_ADD_INVALID_REGISTRY_INPUT", error instanceof Error
                    ? error.message
                    : "Spec add input is not a valid registry entry.", "error")
            ]
        };
    }
    const duplicateEntry = input.currentEntries.find((entry) => entry.id === parsedEntry.id);
    if (duplicateEntry !== undefined) {
        return {
            ok: false,
            findings: [
                createFinding("SPEC_ADD_DUPLICATE_ID", `Spec id '${parsedEntry.id}' already exists in the registry index.`, "error", cli_constants_1.CLI_SPEC_INDEX_PATH)
            ]
        };
    }
    const emergentFinding = validateEmergentSpecPath(parsedEntry);
    if (emergentFinding !== null) {
        return {
            ok: false,
            findings: [emergentFinding]
        };
    }
    return {
        ok: true,
        entry: parsedEntry
    };
}
function validateEmergentSpecPath(entry) {
    if (entry.optional.implementation_order !== EMERGENT_IMPLEMENTATION_ORDER) {
        return null;
    }
    if (EMERGENT_SPEC_PATH_PATTERN.test(entry.spec_path)) {
        return null;
    }
    return createFinding("SPEC_ADD_INVALID_EMERGENT_SPEC_PATH", "Emergent spec entries with implementation_order '00' must use '.day-shift/specs/00-emergent/00-YYYY-MM-DD-<slug>.md'.", "error", entry.spec_path);
}
function readRecord(input, label) {
    if (typeof input !== "object" || input === null || Array.isArray(input)) {
        throw new TypeError(`${label} must be an object.`);
    }
    return input;
}
function createFinding(code, message, severity, path) {
    const finding = {
        code,
        message,
        severity
    };
    if (path !== undefined) {
        finding.path = path;
    }
    return finding;
}
