// engine/schema-parity-auditor/handler-checker.ts — Checks handler files for safe access patterns
import { readFile } from 'node:fs/promises';
import { glob } from 'glob';
/**
 * Finds the handler file for a given tool registration file.
 * Convention: register-foo-tools.ts → foo-handler.ts (or similar).
 */
export async function findHandlerFile(registerFile, projectPath) {
    // Derive handler name from register file:
    // register-foo-bar-tools.ts → foo-bar-handler.ts
    const basename = registerFile.split('/').pop() ?? '';
    const handlerBasename = basename.replace(/^register-/, '').replace(/-tools\.ts$/, '-handler.ts');
    const pattern = `${projectPath}/src/tools/${handlerBasename}`;
    const files = await glob(pattern);
    return files[0];
}
/**
 * Checks whether a handler file accesses an optional field safely.
 * Safe patterns: `field ?? `, `if (field`, `if (!field`, `field?.`
 * Unsafe pattern: `field.method(` or `field.property` without a preceding guard.
 */
export async function checkHandlerAccess(fieldName, handlerFile) {
    const content = await readFile(handlerFile, 'utf-8');
    return checkHandlerContent(fieldName, handlerFile, content);
}
/**
 * Analyses handler content for safe/unsafe access of fieldName.
 * Exported for unit testing.
 */
export function checkHandlerContent(fieldName, handlerFile, content) {
    const escaped = escapeRegex(fieldName);
    // Unsafe: `fieldName.someMethod` or `fieldName.someProp`
    const unsafeRe = new RegExp(`\\b${escaped}\\.\\w+`);
    // Safe: nullish coalescing `fieldName ??` or `fieldName??`
    const nullishRe = new RegExp(`\\b${escaped}\\s*\\?\\?`);
    // Safe: optional chaining `fieldName?.`
    const optChainRe = new RegExp(`\\b${escaped}\\?\\.`);
    // Safe: if-check `if (fieldName`, `if (!fieldName`
    const ifCheckRe = new RegExp(`if\\s*\\([^)]*\\b${escaped}\\b`);
    const hasUnsafeAccess = unsafeRe.test(content);
    const hasNullishCoalescing = nullishRe.test(content);
    const hasOptionalChain = optChainRe.test(content);
    const hasIfCheck = ifCheckRe.test(content);
    // If there is unsafe access but also a safe pattern, the code may be guarded
    const trulyUnsafe = hasUnsafeAccess && !hasNullishCoalescing && !hasOptionalChain && !hasIfCheck;
    return {
        handlerFile,
        hasUnsafeAccess: trulyUnsafe,
        hasNullishCoalescing,
        hasIfCheck,
    };
}
function escapeRegex(str) {
    return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
//# sourceMappingURL=handler-checker.js.map