"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findRequirementExclusionMatch = exports.buildRequirementExclusionHintForVisibleResult = exports.buildRequirementExclusionHint = void 0;
exports.loadEffectiveRequirementExclusions = loadEffectiveRequirementExclusions;
exports.addMachineRequirementExclusion = addMachineRequirementExclusion;
const promises_1 = require("node:fs/promises");
const node_os_1 = __importDefault(require("node:os"));
const node_path_1 = __importDefault(require("node:path"));
const fs_errors_1 = require("../core/fs-errors");
const paths_1 = require("../core/paths");
const metadata_1 = require("./metadata");
const requirement_exclusion_model_1 = require("./requirement-exclusion-model");
var requirement_exclusion_model_2 = require("./requirement-exclusion-model");
Object.defineProperty(exports, "buildRequirementExclusionHint", { enumerable: true, get: function () { return requirement_exclusion_model_2.buildRequirementExclusionHint; } });
Object.defineProperty(exports, "buildRequirementExclusionHintForVisibleResult", { enumerable: true, get: function () { return requirement_exclusion_model_2.buildRequirementExclusionHintForVisibleResult; } });
Object.defineProperty(exports, "findRequirementExclusionMatch", { enumerable: true, get: function () { return requirement_exclusion_model_2.findRequirementExclusionMatch; } });
async function loadEffectiveRequirementExclusions(input) {
    const metadata = await (0, metadata_1.loadEffectiveCatalogMetadata)({
        repoRoot: input.repoRoot,
    });
    const machinePath = (0, paths_1.getMachineCatalogRequirementExclusionsPath)(input.homeDirectory ?? node_os_1.default.homedir());
    const machineFile = await readOptionalMachineRequirementExclusionsFile(machinePath);
    return [
        ...metadata.requirementExclusions,
        ...(0, requirement_exclusion_model_1.requirementExclusionsFileToItems)(machineFile, "machine", machinePath),
    ].sort(requirement_exclusion_model_1.compareRequirementExclusions);
}
async function addMachineRequirementExclusion(input) {
    const filePath = (0, paths_1.getMachineCatalogRequirementExclusionsPath)(input.homeDirectory ?? node_os_1.default.homedir());
    const file = (await readOptionalMachineRequirementExclusionsFile(filePath)) ??
        (0, requirement_exclusion_model_1.emptyMachineRequirementExclusionsFile)();
    const list = input.target === "skill"
        ? file.requirementExclusions.skills
        : file.requirementExclusions.mcp;
    const normalized = (0, requirement_exclusion_model_1.normalizeRequirementExclusionEntry)(input.entry);
    if (list.some((entry) => entry.ref === normalized.ref &&
        entry.id === normalized.id &&
        entry.source === normalized.source)) {
        return { path: filePath, added: false };
    }
    list.push(normalized);
    list.sort(requirement_exclusion_model_1.compareRawRequirementExclusions);
    await (0, promises_1.mkdir)(node_path_1.default.dirname(filePath), { recursive: true });
    await (0, promises_1.writeFile)(filePath, `${JSON.stringify(file, null, 2)}\n`, "utf8");
    return { path: filePath, added: true };
}
async function readOptionalMachineRequirementExclusionsFile(filePath) {
    let content;
    try {
        content = await (0, promises_1.readFile)(filePath, "utf8");
    }
    catch (error) {
        if ((0, fs_errors_1.isMissingFileError)(error)) {
            return null;
        }
        throw new Error(`Failed to read catalog requirement exclusions ${filePath}: ${String(error)}`);
    }
    let json;
    try {
        json = JSON.parse(content);
    }
    catch (error) {
        throw new Error(`Invalid catalog requirement exclusions ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
    }
    const parsed = requirement_exclusion_model_1.machineRequirementExclusionsFileSchema.safeParse(json);
    if (!parsed.success) {
        throw new Error(`Invalid catalog requirement exclusions ${filePath}: ${formatZodIssues(parsed.error.issues)}`);
    }
    return {
        version: parsed.data.version,
        requirementExclusions: (0, requirement_exclusion_model_1.normalizeRequirementExclusions)(parsed.data.requirementExclusions),
    };
}
function formatZodIssues(issues) {
    return issues
        .map((issue) => {
        const location = issue.path.length > 0 ? `${issue.path.join(".")}: ` : "";
        return `${location}${issue.message}`;
    })
        .join("; ");
}
