"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateSpecRegistryRouting = validateSpecRegistryRouting;
exports.parseSpecRegistryRouting = parseSpecRegistryRouting;
exports.assertSpecRegistryRouting = assertSpecRegistryRouting;
const paths_1 = require("../paths");
const destination_1 = require("./destination");
const traceability_1 = require("./traceability");
function validateSpecRegistryRouting(input) {
    return parseSpecRegistryRouting(input);
}
function parseSpecRegistryRouting(input) {
    const destination = input.destination === undefined
        ? undefined
        : (0, destination_1.parseSpecRegistryDestination)(input.destination);
    const specPath = parseSpecRegistrySpecPath(input.spec_path);
    const linkedSlice = input.linked_slice === undefined ? undefined : (0, traceability_1.parseLinkedSliceReference)(input.linked_slice);
    if (linkedSlice !== undefined) {
        if (destination === undefined) {
            throw new TypeError("Linked slice metadata requires a planning destination.");
        }
        const expectedPlanningPaths = getExpectedPlanningOverviewPaths({
            destination: destination.destination,
            specPath,
            linkedSlice,
            implementationOrder: input.implementation_order
        });
        if (!expectedPlanningPaths.includes(linkedSlice.path)) {
            throw new TypeError(`Linked slice path '${linkedSlice.path}' must match planning overview '${expectedPlanningPaths.join("' or '")}'.`);
        }
    }
    return {
        destination: destination?.destination,
        spec_path: specPath.spec_path,
        sliceSlug: specPath.sliceSlug,
        linked_slice: linkedSlice
    };
}
function getExpectedPlanningOverviewPaths(input) {
    const planningRoot = ".day-shift/planning";
    const governedPrefix = `${planningRoot}/governed/`;
    const structuredPrefix = `${planningRoot}/structured/`;
    const linkedPath = input.linkedSlice.path;
    const overviewNames = ["slice-overview.md", "overview.md"];
    if (input.implementationOrder === "00" &&
        input.specPath.sliceSlug === "00-emergent" &&
        input.destination.startsWith("emergent/")) {
        const emergentSlug = input.destination.slice("emergent/".length);
        if (emergentSlug.trim() !== "") {
            const directoryName = `00-emergent-${emergentSlug}`;
            const directory = linkedPath.startsWith(governedPrefix)
                ? `${governedPrefix}${directoryName}`
                : `${planningRoot}/${directoryName}`;
            return overviewNames.map((name) => `${directory}/${name}`);
        }
    }
    if (linkedPath.startsWith(governedPrefix)) {
        const implementationOrder = typeof input.implementationOrder === "string"
            ? input.implementationOrder.trim()
            : typeof input.implementationOrder === "number"
                ? String(input.implementationOrder)
                : "";
        const directoryName = implementationOrder !== ""
            && !input.linkedSlice.slice.startsWith(`${implementationOrder}-`)
            ? `${implementationOrder}-${input.linkedSlice.slice}`
            : input.linkedSlice.slice;
        return [`${governedPrefix}${directoryName}/slice-overview.md`];
    }
    if (linkedPath.startsWith(structuredPrefix)) {
        return [`${structuredPrefix}${input.linkedSlice.slice}/overview.md`];
    }
    const directory = `${planningRoot}/${input.specPath.sliceSlug}`;
    return overviewNames.map((name) => `${directory}/${name}`);
}
function assertSpecRegistryRouting(input) {
    return parseSpecRegistryRouting(input);
}
function parseSpecRegistrySpecPath(input) {
    const repositoryRelativePath = typeof input === "string" ? (0, paths_1.parseRepositoryRelativePath)(input) : input;
    if (typeof input === "string" && input !== repositoryRelativePath.normalizedPath) {
        throw new TypeError(`Spec path must use the canonical repository-relative path '${repositoryRelativePath.normalizedPath}'.`);
    }
    const segments = repositoryRelativePath.segments;
    if (segments.length < 3 || segments[0] !== ".day-shift" || segments[1] !== "specs") {
        throw new TypeError("Spec path must point to a concrete spec file under .day-shift/specs/<slice-slug>/...");
    }
    const sliceSlug = segments.length === 3 ? stripFileExtension(segments[2]) : segments[2];
    if (sliceSlug.trim() === "") {
        throw new TypeError("Spec path must include a non-empty slice slug under .day-shift/specs/.");
    }
    return {
        spec_path: repositoryRelativePath.normalizedPath,
        sliceSlug,
        repositoryRelativePath
    };
}
function stripFileExtension(value) {
    const extensionIndex = value.lastIndexOf(".");
    if (extensionIndex <= 0) {
        return value;
    }
    return value.slice(0, extensionIndex);
}
