"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TRACE_LINK_DISPOSITION_STATUSES = void 0;
exports.createTraceLinkDisposition = createTraceLinkDisposition;
exports.normalizeTraceLinkDispositionTarget = normalizeTraceLinkDispositionTarget;
exports.createTraceLinkDispositionId = createTraceLinkDispositionId;
exports.validateTraceLinkDispositionCollection = validateTraceLinkDispositionCollection;
exports.assertTraceLinkDispositionStatus = assertTraceLinkDispositionStatus;
const paths_1 = require("../paths");
exports.TRACE_LINK_DISPOSITION_STATUSES = ["retired", "deleted", "migrated"];
function createTraceLinkDisposition(input) {
    assertTraceLinkDispositionStatus(input.status);
    const target = normalizeTraceLinkDispositionTarget(input.target);
    const base = {
        id: createTraceLinkDispositionId(target.normalizedPath),
        status: input.status,
        target,
        discovery: input.discovery,
        reason: input.reason,
        createdAt: input.createdAt,
        updatedAt: input.updatedAt ?? input.createdAt,
        applyEvidence: input.applyEvidence
    };
    if (input.status === "migrated") {
        if (input.replacementTarget === undefined) {
            throw new RangeError("Migrated trace-link dispositions require a replacement target.");
        }
        return {
            ...base,
            status: "migrated",
            replacementTarget: normalizeTraceLinkDispositionTarget(input.replacementTarget)
        };
    }
    if (input.replacementTarget !== undefined) {
        throw new RangeError("Replacement targets are only supported for migrated trace-link dispositions.");
    }
    return input.status === "retired"
        ? { ...base, status: "retired" }
        : { ...base, status: "deleted" };
}
function normalizeTraceLinkDispositionTarget(input) {
    const trimmedInput = input.trim();
    if (trimmedInput === "") {
        throw new RangeError("Trace-link disposition targets must not be empty.");
    }
    if (trimmedInput.startsWith("#")) {
        throw new RangeError(`Trace-link disposition targets must include a repository-local path: ${input}`);
    }
    if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(trimmedInput)) {
        throw new RangeError(`Trace-link disposition targets must be repository-local paths: ${input}`);
    }
    const pathWithoutFragment = trimmedInput.split("#", 1)[0];
    const parsed = (0, paths_1.parseRepositoryRelativePath)(pathWithoutFragment);
    if (parsed.normalizedPath.startsWith("node_modules/")) {
        throw new RangeError(`Trace-link disposition targets must stay within supported repository-local surfaces: ${input}`);
    }
    return {
        originalInput: input,
        normalizedPath: parsed.normalizedPath
    };
}
function createTraceLinkDispositionId(normalizedTargetPath) {
    const target = normalizeTraceLinkDispositionTarget(normalizedTargetPath);
    return `target:${target.normalizedPath}`;
}
function validateTraceLinkDispositionCollection(dispositions) {
    const seenIds = new Set();
    for (const disposition of dispositions) {
        assertTraceLinkDispositionStatus(disposition.status);
        const expectedId = createTraceLinkDispositionId(disposition.target.normalizedPath);
        if (disposition.id !== expectedId) {
            throw new RangeError(`Trace-link disposition id '${disposition.id}' does not match target '${disposition.target.normalizedPath}'.`);
        }
        if (disposition.status === "migrated") {
            normalizeTraceLinkDispositionTarget(disposition.replacementTarget.normalizedPath);
        }
        else if ("replacementTarget" in disposition) {
            throw new RangeError("Replacement targets are only supported for migrated trace-link dispositions.");
        }
        if (seenIds.has(disposition.id)) {
            throw new RangeError(`Duplicate trace-link disposition id '${disposition.id}'.`);
        }
        seenIds.add(disposition.id);
    }
}
function assertTraceLinkDispositionStatus(status) {
    if (!exports.TRACE_LINK_DISPOSITION_STATUSES.includes(status)) {
        throw new RangeError(`Unsupported trace-link disposition status '${status}'.`);
    }
}
