"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtractionCascade = void 0;
const regex_extractor_1 = require("./regex-extractor");
const ast_extractor_1 = require("./ast-extractor");
const ast_differ_1 = require("./ast-differ");
const security_predictor_1 = require("../walls/03-knowledge/decisions/security-predictor");
const error_predictor_1 = require("../walls/03-knowledge/decisions/error-predictor");
const python_extractor_1 = require("./python-extractor");
const go_extractor_1 = require("./go-extractor");
const AST_LANGUAGES = new Set(['typescript', 'javascript', 'ts', 'js', 'tsx', 'jsx']);
function detectLanguage(code, hint) {
    if (hint && AST_LANGUAGES.has(hint.toLowerCase()))
        return hint.toLowerCase();
    if (/^\s*import\s+|^\s*export\s+|^\s*interface\s+|^\s*type\s+|:\s*(string|number|boolean|void)\b/m.test(code))
        return 'typescript';
    if (/^\s*(import|export)\s+|const\s+\w+\s*=\s*require|module\.exports/m.test(code))
        return 'javascript';
    if (/^\s*#!|^\s*def\s+|^\s*class\s+\w+.*:/m.test(code))
        return 'python';
    if (/^\s*(package|import)\s+[a-z]+\.[a-z]+|^\s*func\s+|^\s*type\s+\w+\s+struct/m.test(code))
        return 'go';
    return 'unknown';
}
class ExtractionCascade {
    regexExtractor;
    heuristicExtractor;
    astDiffer;
    securityPredictor;
    errorPredictor;
    pythonExtractor;
    goExtractor;
    constructor() {
        this.regexExtractor = new regex_extractor_1.RegexExtractor();
        this.heuristicExtractor = new ast_extractor_1.DiffPatternMatcher();
        this.astDiffer = new ast_differ_1.AstDiffer();
        this.securityPredictor = new security_predictor_1.SecurityPredictor();
        this.errorPredictor = new error_predictor_1.ErrorPredictor();
        this.pythonExtractor = new python_extractor_1.PythonExtractor();
        this.goExtractor = new go_extractor_1.GoExtractor();
    }
    detectLanguage(code, hint) {
        return detectLanguage(code, hint);
    }
    extract(originalCode, editedCode, language) {
        const startTime = performance.now();
        const lang = language || detectLanguage(originalCode || editedCode);
        let astPatterns = [];
        if (AST_LANGUAGES.has(lang)) {
            astPatterns = this.astDiffer.extract(originalCode, editedCode);
        }
        if (astPatterns.length > 0) {
            const latency = Math.round((performance.now() - startTime) * 100) / 100;
            return { patterns: astPatterns, stepUsed: 'ast', latencyMs: latency, language: lang };
        }
        let langPatterns = [];
        if (lang === 'python') {
            langPatterns = this.pythonExtractor.extract(editedCode);
        }
        else if (lang === 'go') {
            langPatterns = this.goExtractor.extract(editedCode);
        }
        if (langPatterns.length > 0) {
            const latency = Math.round((performance.now() - startTime) * 100) / 100;
            return { patterns: langPatterns, stepUsed: 'regex', latencyMs: latency, language: lang };
        }
        const regexPatterns = this.regexExtractor.extractFromDiff(originalCode, editedCode);
        if (regexPatterns.length > 0) {
            const latency = Math.round((performance.now() - startTime) * 100) / 100;
            return { patterns: regexPatterns, stepUsed: 'regex', latencyMs: latency, language: lang };
        }
        const heuristicPatterns = this.heuristicExtractor.extract(originalCode, editedCode);
        if (heuristicPatterns.length > 0) {
            const latency = Math.round((performance.now() - startTime) * 100) / 100;
            return { patterns: heuristicPatterns, stepUsed: 'heuristic', latencyMs: latency, language: lang };
        }
        const latency = Math.round((performance.now() - startTime) * 100) / 100;
        return { patterns: [], stepUsed: 'none', latencyMs: latency, language: lang };
    }
    extractAll(originalCode, editedCode, language) {
        const startTime = performance.now();
        const lang = language || detectLanguage(originalCode || editedCode);
        let astPatterns = [];
        if (AST_LANGUAGES.has(lang)) {
            astPatterns = this.astDiffer.extract(originalCode, editedCode);
        }
        let langPatterns = [];
        if (lang === 'python') {
            langPatterns = this.pythonExtractor.extract(editedCode);
        }
        else if (lang === 'go') {
            langPatterns = this.goExtractor.extract(editedCode);
        }
        const regexPatterns = this.regexExtractor.extractFromDiff(originalCode, editedCode);
        const heuristicPatterns = this.heuristicExtractor.extract(originalCode, editedCode);
        const allPatterns = [...astPatterns, ...langPatterns, ...regexPatterns, ...heuristicPatterns];
        const stepUsed = astPatterns.length > 0 ? 'ast'
            : regexPatterns.length > 0 ? 'regex'
                : heuristicPatterns.length > 0 ? 'heuristic'
                    : 'none';
        const latency = Math.round((performance.now() - startTime) * 100) / 100;
        return { patterns: allPatterns, stepUsed, latencyMs: latency, language: lang };
    }
    audit(code) {
        return {
            security: this.securityPredictor.predict(code),
            errors: this.errorPredictor.predict(code),
        };
    }
    getStats() {
        return {
            astPatterns: 11,
            regexPatterns: this.regexExtractor.getPatternCount(),
            heuristicCapabilities: 4,
        };
    }
}
exports.ExtractionCascade = ExtractionCascade;
//# sourceMappingURL=extraction-cascade.js.map