"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.compareChangedPathsToDeclaredScope = compareChangedPathsToDeclaredScope;
const scope_guard_1 = require("./scope-guard");
function compareChangedPathsToDeclaredScope(input) {
    const explicitDeclaredTargets = input.declaredTargetEvidence
        .filter((entry) => entry.state === "explicit" && entry.path !== undefined)
        .map((entry) => ({
        declaredPath: entry.path,
        sourceArtifactPath: entry.sourceArtifactPath,
        sourceSection: entry.sourceSection
    }));
    const matchGroups = new Map();
    const unmatchedChangedPaths = [];
    const invalidChangedPathEvidence = [];
    const duplicateChangedPathEvidence = [];
    for (const changedPathEvidence of input.changedPathEvidence) {
        if (changedPathEvidence.state === "invalid-input") {
            invalidChangedPathEvidence.push(changedPathEvidence);
            continue;
        }
        if (changedPathEvidence.state === "duplicate") {
            duplicateChangedPathEvidence.push(changedPathEvidence);
            continue;
        }
        const changedPath = changedPathEvidence.normalizedPath;
        if (changedPath === undefined) {
            continue;
        }
        const matchingTarget = explicitDeclaredTargets.find((target) => (0, scope_guard_1.isRequestedPathWithinDeclaredTarget)(changedPath, target.declaredPath));
        if (matchingTarget === undefined) {
            unmatchedChangedPaths.push({
                changedPath,
                comparedDeclaredPaths: explicitDeclaredTargets.map((target) => target.declaredPath)
            });
            continue;
        }
        const groupKey = `${matchingTarget.sourceArtifactPath}\0${matchingTarget.declaredPath}`;
        const existingGroup = matchGroups.get(groupKey);
        if (existingGroup === undefined) {
            matchGroups.set(groupKey, {
                target: matchingTarget,
                changedPaths: [changedPath]
            });
            continue;
        }
        existingGroup.changedPaths.push(changedPath);
    }
    const declarationIssueEvidence = input.declaredTargetEvidence
        .filter(isDeclarationIssueEvidence);
    return {
        matchedGroups: [...matchGroups.values()].map((group) => ({
            declaredPath: group.target.declaredPath,
            sourceArtifactPath: group.target.sourceArtifactPath,
            sourceSection: group.target.sourceSection,
            changedPaths: group.changedPaths
        })),
        unmatchedChangedPaths,
        invalidChangedPathEvidence,
        duplicateChangedPathEvidence,
        declaredScopeEvidence: input.declaredTargetEvidence,
        declarationIssueEvidence,
        declarationIssueStates: unique(declarationIssueEvidence.map((entry) => entry.state)),
        readOnly: true
    };
}
function unique(values) {
    return [...new Set(values)];
}
function isDeclarationIssueEvidence(entry) {
    return entry.state !== "explicit";
}
