import { getMessages } from '../messages/index.js';
import { getGlobalRegistry, initializeDefaultPlugins } from '../../shared/plugins/index.js';
import { parseComBabel, parseComCss, parseComGo, parseComHtmlFunc, parseComJson, parseComMarkdown, parseComPhp, parseComPython, parseComRust, parseComScss, parseComShell, parseComText, parseComTypeScript, parseComVue, parseComXml, parseComYaml, } from './langs/index.js';
import { getCurrentParsingFile, setCurrentParsingFile } from './utils.js';
export { getCurrentParsingFile };
const BUILD_ARTIFACTS = new Set(['.map', '.meta', '.rsc', '.tsbuildinfo', '.example']);
export const PARSERS = new Map([
    ['.js', parseComBabel], ['.jsx', parseComBabel], ['.ts', parseComBabel], ['.tsx', parseComBabel], ['.mjs', parseComBabel], ['.cjs', parseComBabel],
    ['.d.ts', () => null],
    ['.xml', parseComXml], ['.html', parseComHtmlFunc], ['.htm', parseComHtmlFunc], ['.vue', parseComVue],
    ['.css', parseComCss], ['.scss', parseComScss],
    ['.php', parseComPhp], ['.py', parseComPython],
    ['.json', parseComJson],
    ['.yaml', parseComYaml], ['.yml', parseComYaml],
    ['.svg', parseComXml],
    ['.go', parseComGo], ['.rs', parseComRust],
    ['.sh', parseComShell], ['.bash', parseComShell],
    ['.md', parseComMarkdown], ['.mdx', parseComMarkdown],
    ['.txt', parseComText], ['.env', parseComText],
    ...Array.from(BUILD_ARTIFACTS).map(ext => [ext, (() => null)]),
]);
export const EXTENSOES_SUPORTADAS = Array.from(PARSERS.keys()).filter(ext => ext !== '.d.ts');
export function TEM_PARSER(ext) {
    return PARSERS.has(ext);
}
export async function decifrarSintaxe(codigo, ext, opts = {}) {
    setCurrentParsingFile(opts.relPath);
    const parser = PARSERS.get(ext);
    if (!parser) {
        getMessages().logCore.nenhumParser(ext);
        return null;
    }
    if (ext === '.ts' || ext === '.tsx') {
        const caminho = opts.plugins;
        if (Array.isArray(caminho)) {
            const lower = caminho.map(x => String(x).toLowerCase());
            const hasTs = lower.includes('typescript');
            const hasFlow = lower.includes('flow');
            if (!hasTs || hasFlow) {
                const tsx = ext === '.tsx';
                const tsParsed = parseComTypeScript(codigo, tsx);
                if (tsParsed) {
                    setCurrentParsingFile(undefined);
                    return Promise.resolve(tsParsed);
                }
            }
        }
    }
    let parseResultado;
    if (parser === parseComBabel) {
        parseResultado = parseComBabel(codigo, opts.plugins);
    }
    else {
        parseResultado = parser(codigo, opts.plugins);
    }
    if (parseResultado == null && (ext === '.js' || ext === '.mjs' || ext === '.cjs')) {
        try {
            const pareceFlow = /@flow\b/.test(codigo) || /\bimport\s+type\b/.test(codigo);
            if (pareceFlow) {
                parseResultado = parseComBabel(codigo, ['flow', 'jsx', 'decorators-legacy', 'importAttributes', 'importAssertions', 'classProperties', 'classPrivateProperties', 'classPrivateMethods', 'optionalChaining', 'nullishCoalescingOperator', 'topLevelAwait']);
            }
            if (parseResultado == null) {
                parseResultado = parseComBabel(codigo, ['jsx', 'decorators-legacy', 'importAttributes', 'importAssertions', 'classProperties', 'classPrivateProperties', 'classPrivateMethods', 'optionalChaining', 'nullishCoalescingOperator', 'topLevelAwait']);
            }
        }
        catch {
        }
    }
    if (parseResultado == null && (ext === '.ts' || ext === '.tsx')) {
        const tsx = ext === '.tsx';
        const tsParsed = parseComTypeScript(codigo, tsx);
        if (tsParsed) {
            setCurrentParsingFile(undefined);
            return Promise.resolve(tsParsed);
        }
    }
    if (parseResultado == null && opts.plugins && (ext === '.ts' || ext === '.tsx')) {
        const tsx = ext === '.tsx';
        const tsParsed = parseComTypeScript(codigo, tsx);
        if (tsParsed) {
            setCurrentParsingFile(undefined);
            return Promise.resolve(tsParsed);
        }
    }
    if (opts.timeoutMs) {
        return (async () => {
            let timer = null;
            try {
                const race = Promise.race([Promise.resolve(parseResultado), new Promise(resolve => {
                        timer = setTimeout(() => {
                            getMessages().logCore.timeoutParsing(opts.timeoutMs || 0, ext);
                            resolve(null);
                        }, opts.timeoutMs);
                    })]);
                return await race;
            }
            finally {
                if (timer)
                    clearTimeout(timer);
                setCurrentParsingFile(undefined);
            }
        })();
    }
    setCurrentParsingFile(undefined);
    return Promise.resolve(parseResultado ?? null);
}
function initializePluginSystem() {
    const registry = getGlobalRegistry();
    const registeredPlugins = registry.getRegisteredPlugins();
    if (registeredPlugins.length === 0) {
        initializeDefaultPlugins();
        getMessages().log.debug(getMessages().ParserExtraMensagens.pluginsRegistrados);
    }
}
export async function parseComPlugins(codigo, extensao, opts) {
    try {
        initializePluginSystem();
        const registry = getGlobalRegistry();
        const plugin = await registry.getPluginForExtension(extensao);
        if (!plugin) {
            getMessages().logCore.pluginNaoEncontrado(extensao);
            return await decifrarSintaxe(codigo, extensao, {
                plugins: opts?.plugins,
                timeoutMs: opts?.timeoutMs
            });
        }
        getMessages().logCore.usandoPlugin(plugin.name, extensao);
        const pluginOpts = {
            ...opts,
            pluginConfig: {
                ...opts?.pluginConfig,
                extension: extensao
            }
        };
        const result = await plugin.parse(codigo, pluginOpts);
        return result;
    }
    catch (error) {
        getMessages().logCore.sistemaPluginsFalhou(error.message);
        return await decifrarSintaxe(codigo, extensao, {
            plugins: opts?.plugins,
            timeoutMs: opts?.timeoutMs
        });
    }
}
export function getPluginStats() {
    try {
        initializePluginSystem();
        const registry = getGlobalRegistry();
        const stats = registry.getStats();
        return {
            pluginsRegistrados: stats.pluginsRegistrados,
            extensoesSuportadas: stats.extensoesSuportadas,
            pluginsAtivos: stats.pluginsRegistrados > 0
        };
    }
    catch {
        return {
            pluginsRegistrados: 0,
            extensoesSuportadas: 0,
            pluginsAtivos: false
        };
    }
}
//# sourceMappingURL=parser.js.map