"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateAdrEnforcement = validateAdrEnforcement;
const path = __importStar(require("node:path"));
const promises_1 = require("node:fs/promises");
const adrLoader_1 = require("./adrLoader");
const AdrValidationRuleIds = {
    ADR_DIRECTORY_EXISTS: 'AP-ADR-001',
    ADR_FILE_HAS_TITLE: 'AP-ADR-002',
    ADR_STATUS_VALID: 'AP-ADR-003',
    ADR_REQUIRED_COVERAGE_PRESENT: 'AP-ADR-004',
};
function normalizeText(value) {
    return value.trim().toLowerCase();
}
function hasKeywordMatch(record, keywords) {
    const haystack = `${record.fileName} ${record.title} ${record.rawContent}`.toLowerCase();
    return keywords.every((keyword) => haystack.includes(keyword));
}
function pathExists(targetPath) {
    return (0, promises_1.access)(targetPath).then(() => true).catch(() => false);
}
function buildSummary(records) {
    const countByStatus = (status) => records.filter((record) => normalizeText(record.status ?? '') === status).length;
    return {
        total: records.length,
        proposed: countByStatus('proposed'),
        accepted: countByStatus('accepted'),
        deprecated: countByStatus('deprecated'),
        superseded: countByStatus('superseded'),
    };
}
function createAdrValidationResult(input) {
    return {
        id: input.id,
        severity: input.severity ?? 'warning',
        passed: input.passed,
        message: input.message,
        ...(input.sourceFile ? { sourceFile: input.sourceFile } : {}),
    };
}
async function validateAdrEnforcement(workspaceRoot, config) {
    const adrDirectoryRelativePath = await (0, adrLoader_1.resolveAdrDirectoryRelativePath)(workspaceRoot);
    const adrDirectory = (0, adrLoader_1.getAdrDirectoryPath)(workspaceRoot, adrDirectoryRelativePath);
    const adrDirectoryExists = await pathExists(adrDirectory);
    if (!adrDirectoryExists) {
        return {
            results: [
                createAdrValidationResult({
                    id: AdrValidationRuleIds.ADR_DIRECTORY_EXISTS,
                    passed: false,
                    message: `${adrDirectoryRelativePath}/ is missing. Create the ADR directory to document architecture decisions.`,
                }),
            ],
        };
    }
    const records = await (0, adrLoader_1.loadArchitectureDecisionRecords)(workspaceRoot, {
        adrDirectoryRelativePath,
    });
    const results = [];
    for (const record of records) {
        results.push(createAdrValidationResult({
            id: AdrValidationRuleIds.ADR_FILE_HAS_TITLE,
            passed: record.title.trim().length > 0,
            message: record.title.trim().length > 0
                ? `${record.filePath} includes a top-level ADR title.`
                : `${record.filePath} is missing a top-level H1 ADR title.`,
            sourceFile: record.filePath,
        }));
        const statusValue = normalizeText(record.status ?? '');
        const hasSupportedStatus = statusValue === 'proposed' ||
            statusValue === 'accepted' ||
            statusValue === 'deprecated' ||
            statusValue === 'superseded';
        results.push(createAdrValidationResult({
            id: AdrValidationRuleIds.ADR_STATUS_VALID,
            passed: hasSupportedStatus,
            message: hasSupportedStatus
                ? `${record.filePath} uses ADR status '${record.status}'.`
                : `${record.filePath} should define ADR status as proposed, accepted, deprecated, or superseded.`,
            sourceFile: record.filePath,
        }));
    }
    const summary = buildSummary(records);
    const requiredCoverageChecks = [
        {
            keywords: ['architecture'],
            label: 'architecture style',
            message: 'Add at least one ADR related to the selected architecture style.',
        },
        {
            keywords: ['dependency', 'governance'],
            label: 'dependency governance',
            message: 'Add at least one ADR related to dependency governance or module boundaries when dependency rules or contracts are present.',
        },
        ...(config.apiStyle === 'none'
            ? []
            : [
                {
                    keywords: config.apiStyle === 'graphql'
                        ? ['api', 'graphql']
                        : ['api', 'rest'],
                    label: `API style (${config.apiStyle})`,
                    message: `Add at least one ADR related to API style (${config.apiStyle}).`,
                },
            ]),
    ];
    const dependencyContextExists = (await pathExists(path.join(workspaceRoot, '.archpilot', 'dependency-rules.json'))) ||
        (await pathExists(path.join(workspaceRoot, '.archpilot', 'contracts')));
    const checksToRun = [
        requiredCoverageChecks[0],
        ...(dependencyContextExists ? [requiredCoverageChecks[1]] : []),
        ...(requiredCoverageChecks[2] ? [requiredCoverageChecks[2]] : []),
    ];
    for (const check of checksToRun) {
        const matched = records.some((record) => hasKeywordMatch(record, check.keywords));
        results.push(createAdrValidationResult({
            id: AdrValidationRuleIds.ADR_REQUIRED_COVERAGE_PRESENT,
            passed: matched,
            message: matched
                ? `Required ADR coverage found for ${check.label}.`
                : check.message,
        }));
    }
    return { results, summary };
}
//# sourceMappingURL=adrValidation.js.map