const AUTO_THRESHOLD_RATIO = 0.3;
const AUTO_THRESHOLD_MIN = 2;
export function chooseClosestIdentifier(input, candidates) {
    if (candidates.length === 0) {
        return undefined;
    }
    const normalizedInput = normalizeIdentifier(input);
    let bestName;
    let bestScore = Number.POSITIVE_INFINITY;
    for (const candidate of candidates) {
        if (candidate === input) {
            return { kind: 'auto', value: candidate };
        }
        const normalizedCandidate = normalizeIdentifier(candidate);
        if (normalizedCandidate === normalizedInput) {
            return { kind: 'auto', value: candidate };
        }
        if (candidate.toLowerCase() === input.toLowerCase()) {
            return { kind: 'auto', value: candidate };
        }
        const score = levenshtein(normalizedInput, normalizedCandidate);
        if (score < bestScore) {
            bestScore = score;
            bestName = candidate;
        }
    }
    if (!bestName) {
        return undefined;
    }
    const normalizedBest = normalizeIdentifier(bestName);
    const lengthBaseline = Math.max(normalizedInput.length, normalizedBest.length, 1);
    const threshold = Math.max(AUTO_THRESHOLD_MIN, Math.floor(lengthBaseline * AUTO_THRESHOLD_RATIO));
    if (bestScore <= threshold) {
        return { kind: 'auto', value: bestName };
    }
    return { kind: 'suggest', value: bestName };
}
export function normalizeIdentifier(value) {
    return value.replace(/[^a-z0-9]/gi, '').toLowerCase();
}
export function renderIdentifierResolutionMessages(context) {
    const resolvedDisplay = context.entity === 'tool' && context.scope
        ? `${context.scope}.${context.resolution.value}`
        : context.resolution.value;
    const attemptedDisplay = context.entity === 'tool' && context.scope ? `${context.scope}.${context.attempted}` : context.attempted;
    if (context.resolution.kind === 'auto') {
        const noun = context.entity === 'tool' ? 'tool call' : 'server name';
        return {
            auto: `[mcporter] Auto-corrected ${noun} to ${resolvedDisplay} (input: ${attemptedDisplay}).`,
        };
    }
    return {
        suggest: `[mcporter] Did you mean ${resolvedDisplay}?`,
    };
}
function levenshtein(a, b) {
    if (a === b) {
        return 0;
    }
    if (a.length === 0) {
        return b.length;
    }
    if (b.length === 0) {
        return a.length;
    }
    const previous = Array.from({ length: b.length + 1 }, (_, index) => index);
    const current = Array.from({ length: b.length + 1 }, () => 0);
    for (let i = 1; i <= a.length; i += 1) {
        current[0] = i;
        const charA = a[i - 1];
        for (let j = 1; j <= b.length; j += 1) {
            const charB = b[j - 1];
            const insertCost = (current[j - 1] ?? Number.POSITIVE_INFINITY) + 1;
            const deleteCost = (previous[j] ?? Number.POSITIVE_INFINITY) + 1;
            const replaceCost = (previous[j - 1] ?? Number.POSITIVE_INFINITY) + (charA === charB ? 0 : 1);
            current[j] = Math.min(insertCost, deleteCost, replaceCost);
        }
        for (let j = 0; j <= b.length; j += 1) {
            previous[j] = current[j] ?? Number.POSITIVE_INFINITY;
        }
    }
    return previous[b.length] ?? Number.POSITIVE_INFINITY;
}
//# sourceMappingURL=identifier-helpers.js.map