"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeDependencySyncState = normalizeDependencySyncState;
exports.shouldAutoBlockOnOverlappingPaths = shouldAutoBlockOnOverlappingPaths;
exports.classifyWorkflowTouchedPath = classifyWorkflowTouchedPath;
exports.toDesiredManagedDependency = toDesiredManagedDependency;
exports.reconcileDependencySyncState = reconcileDependencySyncState;
exports.resolveManagedDependencyHandling = resolveManagedDependencyHandling;
exports.buildDependencyTrackerOperations = buildDependencyTrackerOperations;
exports.areDependencySyncStatesEqual = areDependencySyncStatesEqual;
const node_crypto_1 = require("node:crypto");
function normalizeDependencySyncState(dependencySyncState) {
    return {
        managedDependencies: [...(dependencySyncState?.managedDependencies ?? [])],
        appliedAutoBlockers: [...(dependencySyncState?.appliedAutoBlockers ?? [])],
    };
}
function shouldAutoBlockOnOverlappingPaths(paths) {
    return paths.some((path) => classifyWorkflowTouchedPath(path) === "implementation-affecting");
}
function classifyWorkflowTouchedPath(path) {
    void path;
    return "implementation-affecting";
}
function toDesiredManagedDependency(dependency) {
    return {
        ...dependency,
        scopeDigest: buildOverlappingPathsScopeDigest(dependency.overlappingPaths),
    };
}
function reconcileDependencySyncState(input) {
    const now = new Date().toISOString();
    const existingManagedByKey = new Map(input.existing.managedDependencies.map((dependency) => [
        buildManagedDependencyKey(dependency.issueId, dependency.scopeDigest),
        dependency,
    ]));
    const existingAppliedByKey = new Map(input.existing.appliedAutoBlockers.map((dependency) => [
        buildManagedDependencyKey(dependency.issueId, dependency.scopeDigest),
        dependency,
    ]));
    const managedDependencies = input.strategy === "none"
        ? []
        : input.desired.map((dependency) => {
            const previous = existingManagedByKey.get(buildManagedDependencyKey(dependency.issueId, dependency.scopeDigest));
            return {
                issueId: dependency.issueId,
                scopeDigest: dependency.scopeDigest,
                overlappingPaths: [...dependency.overlappingPaths],
                recordedAt: previous?.recordedAt ?? now,
                completionRequeuedAt: previous?.completionRequeuedAt ?? null,
            };
        });
    const appliedAutoBlockers = input.strategy !== "block"
        ? []
        : input.desired.map((dependency) => {
            const previous = existingAppliedByKey.get(buildManagedDependencyKey(dependency.issueId, dependency.scopeDigest));
            return {
                issueId: dependency.issueId,
                scopeDigest: dependency.scopeDigest,
                overlappingPaths: [...dependency.overlappingPaths],
                recordedAt: previous?.recordedAt ?? now,
            };
        });
    return {
        managedDependencies,
        appliedAutoBlockers,
    };
}
function resolveManagedDependencyHandling(strategy, dependency) {
    if (strategy === "none") {
        return "none";
    }
    if (strategy === "block") {
        return "block";
    }
    if (strategy === "parallel_comment") {
        return "parallel_comment";
    }
    void dependency;
    return "parallel_comment";
}
function buildDependencyTrackerOperations(input) {
    const liveBlockerIds = new Set(input.liveBlockers.map((blocker) => blocker.id));
    const desiredIssueIds = new Set(input.desired.map((dependency) => dependency.issueId));
    if (input.strategy === "block") {
        return {
            addIssueIds: input.desired
                .filter((dependency) => !liveBlockerIds.has(dependency.issueId))
                .map((dependency) => dependency.issueId),
            removeIssueIds: input.existing.appliedAutoBlockers
                .map((dependency) => dependency.issueId)
                .filter((issueId, index, entries) => entries.indexOf(issueId) === index && !desiredIssueIds.has(issueId)),
        };
    }
    return {
        addIssueIds: [],
        removeIssueIds: input.existing.appliedAutoBlockers
            .map((dependency) => dependency.issueId)
            .filter((issueId, index, entries) => entries.indexOf(issueId) === index && liveBlockerIds.has(issueId)),
    };
}
function areDependencySyncStatesEqual(left, right) {
    return (JSON.stringify(normalizeDependencySyncState(left)) ===
        JSON.stringify(normalizeDependencySyncState(right)));
}
function buildManagedDependencyKey(issueId, scopeDigest) {
    return `${issueId}\u0000${scopeDigest}`;
}
function buildOverlappingPathsScopeDigest(paths) {
    return (0, node_crypto_1.createHash)("sha256")
        .update([...paths].sort().join("\n"), "utf8")
        .digest("hex");
}
