// engine/living-spec/signature-tracker.ts — Extract and track exported function signatures
// AST-free: uses regex-based extraction from TypeScript source files.
// Supports: export function, export const arrow, export async function, export default
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
/**
 * Regex patterns for exported function signatures in TypeScript.
 * Each pattern captures: name, params, returnType
 */
const EXPORT_PATTERNS = [
    // export function foo(params): ReturnType
    /^export\s+(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)\s*:\s*([^{]+)/,
    // export const foo = (params): ReturnType =>
    /^export\s+const\s+(\w+)\s*=\s*(?:async\s+)?\(([^)]*)\)\s*:\s*([^=>{]+)/,
    // export default function foo(params): ReturnType
    /^export\s+default\s+(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)\s*:\s*([^{]+)/,
];
/**
 * Extract exported function signatures from a TypeScript file content.
 */
export function extractSignaturesFromContent(content, file) {
    const signatures = [];
    const lines = content.split('\n');
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        if (line === undefined) {
            continue;
        }
        const trimmed = line.trim();
        if (!trimmed.startsWith('export')) {
            continue;
        }
        for (const pattern of EXPORT_PATTERNS) {
            const match = pattern.exec(trimmed);
            if (match?.[1]) {
                signatures.push({
                    name: match[1],
                    params: normalizeWhitespace(match[2] ?? ''),
                    returnType: normalizeWhitespace(match[3] ?? 'unknown'),
                    file,
                    line: i + 1,
                });
                break;
            }
        }
    }
    return signatures;
}
/**
 * Normalize whitespace in type strings for consistent comparison.
 */
function normalizeWhitespace(str) {
    return str.trim().replace(/\s+/g, ' ');
}
/**
 * Extract exported function signatures from a file on disk.
 */
export async function extractSignaturesFromFile(projectPath, relativePath) {
    try {
        const content = await readFile(join(projectPath, relativePath), 'utf-8');
        return extractSignaturesFromContent(content, relativePath);
    }
    catch {
        return [];
    }
}
/**
 * Extract signatures from multiple files.
 */
export async function extractSignaturesFromFiles(projectPath, relativePaths) {
    const all = [];
    for (const path of relativePaths) {
        // Only process TypeScript/JavaScript files
        if (/\.[tj]sx?$/.test(path)) {
            const sigs = await extractSignaturesFromFile(projectPath, path);
            all.push(...sigs);
        }
    }
    return all;
}
/**
 * Compare two sets of signatures to find added, modified, and removed.
 */
export function diffSignatures(previous, current) {
    const changes = [];
    const prevMap = new Map();
    for (const sig of previous) {
        prevMap.set(`${sig.file}::${sig.name}`, sig);
    }
    const currMap = new Map();
    for (const sig of current) {
        currMap.set(`${sig.file}::${sig.name}`, sig);
    }
    // Check for added and modified
    for (const [key, curr] of currMap) {
        const prev = prevMap.get(key);
        if (!prev) {
            changes.push({
                name: curr.name,
                file: curr.file,
                changeType: 'added',
                before: '',
                after: formatSignature(curr),
            });
        }
        else if (prev.params !== curr.params || prev.returnType !== curr.returnType) {
            changes.push({
                name: curr.name,
                file: curr.file,
                changeType: 'modified',
                before: formatSignature(prev),
                after: formatSignature(curr),
            });
        }
    }
    // Check for removed
    for (const [key, prev] of prevMap) {
        if (!currMap.has(key)) {
            changes.push({
                name: prev.name,
                file: prev.file,
                changeType: 'removed',
                before: formatSignature(prev),
                after: '',
            });
        }
    }
    return changes;
}
/**
 * Format a signature as a human-readable string.
 */
function formatSignature(sig) {
    return `${sig.name}(${sig.params}): ${sig.returnType}`;
}
//# sourceMappingURL=signature-tracker.js.map