"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateSpecRegistrySemanticMetadata = validateSpecRegistrySemanticMetadata;
const cli_constants_1 = require("../config/cli-constants");
const destination_1 = require("./destination");
const routing_1 = require("./routing");
const read_helpers_1 = require("./read-helpers");
const source_1 = require("./source");
function validateSpecRegistrySemanticMetadata(entries) {
    const findings = [];
    const skippedEntries = [];
    let checkedEntries = 0;
    for (let index = 0; index < entries.length; index += 1) {
        const entry = entries[index];
        if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
            skippedEntries.push(index);
            continue;
        }
        const record = entry;
        const destination = record.destination;
        const specPath = record.spec_path;
        const source = record.source;
        if (!(0, read_helpers_1.hasRequiredValue)(specPath) || !(0, read_helpers_1.hasRequiredValue)(source)) {
            skippedEntries.push(index);
            continue;
        }
        checkedEntries += 1;
        if (destination !== undefined && typeof destination !== "string") {
            findings.push(createSemanticFinding("SPEC_REGISTRY_INVALID_DESTINATION", index, "invalid destination metadata", "Spec index entry field 'destination' must be a non-empty string."));
        }
        else if (typeof destination === "string") {
            const destinationValidation = (0, destination_1.validateSpecRegistryDestination)(destination);
            if (!destinationValidation.ok) {
                findings.push(createSemanticFinding("SPEC_REGISTRY_INVALID_DESTINATION", index, "invalid destination metadata", destinationValidation.rejection.reason));
            }
        }
        try {
            (0, source_1.parseSpecRegistrySourceReference)(source);
        }
        catch (error) {
            findings.push(createSemanticFinding("SPEC_REGISTRY_INVALID_SOURCE_REFERENCE", index, "invalid source metadata", (0, read_helpers_1.toErrorMessage)(error, "Spec source metadata is invalid.")));
        }
        if (typeof specPath !== "string") {
            findings.push(createSemanticFinding("SPEC_REGISTRY_INVALID_TRACEABILITY", index, "invalid routing or traceability metadata", "Spec index entry field 'spec_path' must be a non-empty string."));
            continue;
        }
        try {
            (0, routing_1.parseSpecRegistryRouting)({
                ...(typeof destination === "string" ? { destination } : {}),
                spec_path: specPath,
                linked_slice: record.linked_slice,
                implementation_order: record.implementation_order
            });
        }
        catch (error) {
            findings.push(createSemanticFinding("SPEC_REGISTRY_INVALID_TRACEABILITY", index, "invalid routing or traceability metadata", (0, read_helpers_1.toErrorMessage)(error, "Spec routing metadata is invalid.")));
        }
    }
    return {
        hasErrors: findings.length > 0,
        findings: Object.freeze(findings),
        checkedEntries,
        skippedEntries: Object.freeze(skippedEntries)
    };
}
function createSemanticFinding(code, index, summary, details) {
    return {
        code,
        message: `Spec index entry at specs[${index}] has ${summary}: ${details}`,
        severity: "error",
        path: cli_constants_1.CLI_SPEC_INDEX_PATH
    };
}
