import { messages } from '../../core/messages/index.js';
const { log, logCore } = messages;
export class PluginRegistry {
    plugins = new Map();
    extensionMap = new Map();
    config;
    userConfiguredEnabled = false;
    languageSupport;
    loadingPromises = new Map();
    constructor(config, languageSupport) {
        this.config = {
            enabled: ['core'],
            autoload: true,
            registry: '@tutanus/plugins',
            ...config
        };
        this.userConfiguredEnabled = !!config?.enabled;
        this.languageSupport = languageSupport || {};
    }
    registerPlugin(plugin) {
        logCore.registrandoPlugin(plugin.name, plugin.version);
        this.validatePlugin(plugin);
        this.plugins.set(plugin.name, plugin);
        for (const ext of plugin.extensions) {
            if (this.extensionMap.has(ext)) {
                const existing = this.extensionMap.get(ext);
                const msg = messages.PluginRegistryMensagens.extensaoSobrescrita;
                log.debug(msg.replace('{ext}', ext).replace('{existente}', existing || '').replace('{novo}', plugin.name));
            }
            this.extensionMap.set(ext, plugin.name);
        }
        const msgRegistrado = messages.PluginRegistryMensagens.pluginRegistrado;
        log.debug(msgRegistrado.replace('{nome}', plugin.name).replace('{extensoes}', plugin.extensions.join(', ')));
    }
    async loadPlugin(name) {
        if (this.plugins.has(name)) {
            const plugin = this.plugins.get(name);
            if (!plugin) {
                throw new Error(messages.ExcecoesMensagens.pluginRegistradoNaoPodeSerObtido(name));
            }
            return plugin;
        }
        if (this.loadingPromises.has(name)) {
            const promise = this.loadingPromises.get(name);
            if (!promise) {
                throw new Error(messages.ExcecoesMensagens.pluginCarregandoPromiseNaoPodeSerObtida(name));
            }
            return promise;
        }
        const loadingPromise = this.doLoadPlugin(name);
        this.loadingPromises.set(name, loadingPromise);
        try {
            const plugin = await loadingPromise;
            this.loadingPromises.delete(name);
            return plugin;
        }
        catch (error) {
            this.loadingPromises.delete(name);
            throw error;
        }
    }
    async doLoadPlugin(name) {
        const msgCarregando = messages.PluginRegistryMensagens.carregandoPlugin;
        log.debug(msgCarregando.replace('{nome}', name));
        try {
            const pluginCaminho = `${this.config.registry}/${name}-plugin`;
            const dynImport = globalThis.import || ((caminho) => import(caminho));
            const pluginModule = await dynImport(pluginCaminho);
            const plugin = pluginModule.default || pluginModule;
            this.validatePlugin(plugin);
            this.registerPlugin(plugin);
            return plugin;
        }
        catch (error) {
            logCore.erroCarregarPlugin(name, error.message);
            throw new Error(messages.ExcecoesMensagens.naoFoiPossivelCarregarPlugin(name, error.message));
        }
    }
    async getPluginForExtension(extension) {
        const pluginNome = this.extensionMap.get(extension);
        if (!pluginNome) {
            if (this.config.autoload) {
                logCore.tentandoAutoload(extension);
                const inferredNome = this.inferPluginName(extension);
                if (inferredNome && this.config.enabled.includes(inferredNome)) {
                    try {
                        return await this.loadPlugin(inferredNome);
                    }
                    catch {
                        logCore.autoloadFalhou(inferredNome);
                    }
                }
            }
            return null;
        }
        if (this.userConfiguredEnabled && !this.config.enabled.includes(pluginNome)) {
            const msgDesabilitado = messages.PluginRegistryMensagens.pluginDesabilitado;
            log.debug(msgDesabilitado.replace('{nome}', pluginNome).replace('{extensao}', extension));
            return null;
        }
        const langChave = extension.substring(1);
        const langSuporte = this.languageSupport[langChave];
        if (langSuporte && !langSuporte.enabled) {
            const msgLinguagem = messages.PluginRegistryMensagens.linguagemDesabilitada;
            log.debug(msgLinguagem.replace('{linguagem}', langChave));
            return null;
        }
        return await this.loadPlugin(pluginNome);
    }
    inferPluginName(extension) {
        const extMap = {
            '.xml': 'core',
            '.html': 'core',
            '.htm': 'core',
            '.css': 'core',
            '.js': 'core',
            '.jsx': 'core',
            '.ts': 'core',
            '.tsx': 'core',
            '.mjs': 'core',
            '.cjs': 'core',
            '.php': 'core',
            '.py': 'core'
        };
        return extMap[extension] || null;
    }
    validatePlugin(plugin) {
        if (!plugin.name || typeof plugin.name !== 'string') {
            throw new Error(messages.ExcecoesMensagens.pluginDeveTerNomeValido);
        }
        if (!plugin.version || typeof plugin.version !== 'string') {
            throw new Error(messages.ExcecoesMensagens.pluginDeveTerVersaoValida);
        }
        if (!Array.isArray(plugin.extensions) || plugin.extensions.length === 0) {
            throw new Error(messages.ExcecoesMensagens.pluginDeveDefinirPeloMenosUmaExtensao);
        }
        if (typeof plugin.parse !== 'function') {
            throw new Error(messages.ExcecoesMensagens.pluginDeveImplementarMetodoParse);
        }
    }
    getRegisteredPlugins() {
        return Array.from(this.plugins.keys());
    }
    getSupportedExtensions() {
        return Array.from(this.extensionMap.keys());
    }
    getStats() {
        return {
            pluginsRegistrados: this.plugins.size,
            extensoesSuportadas: this.extensionMap.size,
            pluginsHabilitados: this.config.enabled.length,
            autoloadAtivo: this.config.autoload
        };
    }
    updateConfig(newConfig) {
        this.config = {
            ...this.config,
            ...newConfig
        };
        if (Object.prototype.hasOwnProperty.call(newConfig, 'enabled')) {
            this.userConfiguredEnabled = true;
        }
        log.debug(messages.PluginRegistryMensagens.configAtualizada);
    }
    updateLanguageSupport(newSupport) {
        this.languageSupport = {
            ...this.languageSupport,
            ...newSupport
        };
        log.debug(messages.PluginRegistryMensagens.suporteAtualizado);
    }
    clearCache() {
        this.plugins.clear();
        this.extensionMap.clear();
        this.loadingPromises.clear();
        log.debug(messages.PluginRegistryMensagens.cacheLimpo);
    }
}
let globalRegistro = null;
export function getGlobalRegistry() {
    if (!globalRegistro) {
        globalRegistro = new PluginRegistry();
    }
    return globalRegistro;
}
export function configureGlobalRegistry(config, languageSupport) {
    globalRegistro = new PluginRegistry(config, languageSupport);
}
export function resetGlobalRegistry() {
    globalRegistro = null;
}
//# sourceMappingURL=registry.js.map