"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSuppressionExpiryState = getSuppressionExpiryState;
exports.evaluateSuppressions = evaluateSuppressions;
const validationSuppressions_1 = require("../validationSuppressions");
const SuppressionRuleIds = {
    MISSING_REASON: 'AP-SUP-001',
    EXPIRED: 'AP-SUP-002',
    UNUSED: 'AP-SUP-003',
    DUPLICATE: 'AP-SUP-004',
    INVALID_EXPIRY_FORMAT: 'AP-SUP-005',
};
function isIsoDateFormat(value) {
    if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
        return false;
    }
    const parsed = new Date(`${value}T00:00:00.000Z`);
    return !Number.isNaN(parsed.getTime()) && parsed.toISOString().slice(0, 10) === value;
}
function getSuppressionExpiryState(entry, todayIsoDate) {
    if (!entry.expiresOn) {
        return 'none';
    }
    if (!isIsoDateFormat(entry.expiresOn)) {
        return 'invalid-format';
    }
    return entry.expiresOn < todayIsoDate ? 'expired' : 'valid';
}
function createValidationResult(input) {
    return {
        id: input.id,
        severity: input.severity,
        passed: false,
        message: input.message,
    };
}
function evaluateSuppressions(input) {
    const matchedCounts = new Map();
    for (const result of input.suppressedResults) {
        const matchedEntry = input.suppressions.find((entry) => entry.ruleId === result.id &&
            (0, validationSuppressions_1.getSuppressionScopeLabel)(entry) === result.suppressionPath &&
            (entry.reason ?? '') === (result.suppressionReason ?? ''));
        if (!matchedEntry) {
            continue;
        }
        matchedCounts.set(matchedEntry.index, (matchedCounts.get(matchedEntry.index) ?? 0) + 1);
    }
    const duplicateCounts = new Map();
    for (const suppression of input.suppressions) {
        const duplicateKey = `${suppression.ruleId}::${suppression.scope ?? ''}`;
        duplicateCounts.set(duplicateKey, (duplicateCounts.get(duplicateKey) ?? 0) + 1);
    }
    const entries = input.suppressions.map((entry) => {
        const expiryState = getSuppressionExpiryState(entry, input.todayIsoDate);
        const matchedFindings = matchedCounts.get(entry.index) ?? 0;
        const duplicateKey = `${entry.ruleId}::${entry.scope ?? ''}`;
        const duplicate = (duplicateCounts.get(duplicateKey) ?? 0) > 1;
        return {
            entry,
            status: expiryState === 'expired'
                ? 'expired'
                : matchedFindings > 0
                    ? 'active'
                    : 'unused',
            matchedFindings,
            expiryState,
            missingReason: !entry.reason || entry.reason.trim().length === 0,
            duplicate,
        };
    });
    const validationResults = [];
    for (const evaluation of entries) {
        const scopeLabel = (0, validationSuppressions_1.getSuppressionScopeLabel)(evaluation.entry);
        if (evaluation.missingReason) {
            validationResults.push(createValidationResult({
                id: SuppressionRuleIds.MISSING_REASON,
                severity: 'warning',
                message: `Suppression ${evaluation.entry.ruleId} at ${scopeLabel} is missing a reason.`,
            }));
        }
        if (evaluation.expiryState === 'expired') {
            validationResults.push(createValidationResult({
                id: SuppressionRuleIds.EXPIRED,
                severity: 'warning',
                message: `Suppression ${evaluation.entry.ruleId} at ${scopeLabel} expired on ${evaluation.entry.expiresOn}.`,
            }));
        }
        if (evaluation.expiryState === 'invalid-format') {
            validationResults.push(createValidationResult({
                id: SuppressionRuleIds.INVALID_EXPIRY_FORMAT,
                severity: 'warning',
                message: `Suppression ${evaluation.entry.ruleId} at ${scopeLabel} has invalid expiresOn format: ${evaluation.entry.expiresOn}.`,
            }));
        }
        if (evaluation.status === 'unused' && evaluation.expiryState !== 'expired') {
            validationResults.push(createValidationResult({
                id: SuppressionRuleIds.UNUSED,
                severity: 'info',
                message: `Suppression ${evaluation.entry.ruleId} at ${scopeLabel} does not match any active finding.`,
            }));
        }
        if (evaluation.duplicate) {
            validationResults.push(createValidationResult({
                id: SuppressionRuleIds.DUPLICATE,
                severity: 'warning',
                message: `Suppression ${evaluation.entry.ruleId} at ${scopeLabel} duplicates another suppression entry.`,
            }));
        }
    }
    const summary = {
        configuredSuppressions: entries.length,
        activeSuppressions: entries.filter((entry) => entry.status === 'active').length,
        expiredSuppressions: entries.filter((entry) => entry.status === 'expired').length,
        unusedSuppressions: entries.filter((entry) => entry.status === 'unused').length,
        findingsSuppressed: input.suppressedResults.length,
    };
    return { entries, summary, validationResults };
}
//# sourceMappingURL=suppressionValidator.js.map