#!/usr/bin/env node
import { realpathSync } from 'node:fs';
import { dirname, join, resolve as resolvePath } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { registrarComandos } from '../cli/index.js';
import { comandoPerf } from '../cli/commands/index.js';
import { ExitCode, sair } from '../cli/helpers/index.js';
import { aplicarConfigParcial, chalk, config, inicializarConfigDinamica } from '../core/config/index.js';
import { getMessages, ICONES_NIVEL } from '../core/messages/index.js';
import { getDefaultMemory } from '../shared/index.js';
import { lerArquivoTexto } from '../shared/persistence/index.js';
import { Command } from 'commander';
import { extrairMensagemErro } from '../types/index.js';
const { log, CliBinMensagens } = getMessages();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
function hasStack(err) {
    return typeof err === 'object' && err !== null && 'stack' in err;
}
function logErroStack(err) {
    if (hasStack(err)) {
        console.error(err.stack);
    }
}
async function registrarLoader() {
    try {
        const distRaiz = resolvePath(__dirname, '..');
        const loaderCaminho = resolvePath(distRaiz, 'node.loader.js');
        const loaderUrl = pathToFileURL(loaderCaminho).toString();
        const { register } = await import('node:module');
        if (typeof register === 'function') {
            register(loaderUrl, pathToFileURL('./'));
        }
    }
    catch (err) {
        log.debug(`Aviso: Não foi possível registrar o loader de aliases: ${err instanceof Error ? err.message : String(err)}`);
    }
}
async function getVersion() {
    try {
        const packageCaminho = join(__dirname, '..', '..', 'package.json');
        const raw = await lerArquivoTexto(packageCaminho);
        if (!raw)
            return '0.0.0';
        const pkg = JSON.parse(raw);
        return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
    }
    catch (err) {
        log.debug(`Erro ao obter versão em getVersion: ${err instanceof Error ? err.message : String(err)}`);
        return '0.0.0';
    }
}
const program = new Command();
async function aplicarFlagsGlobais(opts) {
    if (typeof opts !== 'object' || opts === null) {
        return;
    }
    const flags = opts;
    try {
        const { sanitizarFlags } = await import('../shared/validation/index.js');
        sanitizarFlags(flags);
    }
    catch (erro) {
        const mensagemErro = erro instanceof Error ? erro.message : String(erro);
        console.error(chalk.red(CliBinMensagens.flagsInvalidas.replace('{erro}', mensagemErro)));
        sair(ExitCode.InvalidUsage);
    }
    config.REPORT_SILENCE_LOGS = Boolean(flags.silence);
    config.REPORT_EXPORT_ENABLED = Boolean(flags.export);
    config.REPORT_EXPORT_FULL = Boolean(flags.exportFull);
    const debugAtivo = Boolean(flags.debug) || process.env.TUTANUS_DEBUG === 'true';
    config.DEV_MODE = debugAtivo;
    config.SCAN_ONLY = Boolean(flags.scanOnly);
    config.VERBOSE = flags.silence ? false : Boolean(flags.verbose);
    const overrides = {};
    if (typeof flags.logEstruturado === 'boolean')
        overrides.LOG_ESTRUTURADO = flags.logEstruturado;
    if (typeof flags.incremental === 'boolean')
        overrides.ANALISE_INCREMENTAL_ENABLED = flags.incremental;
    if (typeof flags.metricas === 'boolean')
        overrides.ANALISE_METRICAS_ENABLED = flags.metricas;
    if (Object.keys(overrides).length)
        aplicarConfigParcial(overrides);
}
async function carregarConfigProducao() {
    if (process.env.NODE_ENV !== 'production')
        return;
    try {
        const safeCfgCaminho = join(__dirname, '..', '..', 'tutanus.config.safe.json');
        const raw = await lerArquivoTexto(safeCfgCaminho);
        if (!raw)
            return;
        const safeCfg = JSON.parse(raw);
        const prod = safeCfg?.productionDefaults;
        if (prod && typeof prod === 'object') {
            for (const [chave, valor] of Object.entries(prod)) {
                if (process.env[chave] === undefined)
                    process.env[chave] = String(valor);
            }
        }
    }
    catch (err) {
        log.debug(`Aviso: Configurações de produção não carregadas: ${err instanceof Error ? err.message : String(err)}`);
    }
}
function __tutanus_unhandledRejectionHandler(err) {
    const MARCADOR = CliBinMensagens.unhandledRejection;
    const mensagem = extrairMensagemErro(err);
    console.error(MARCADOR, mensagem);
    if (!process.env.VITEST) {
        logErroStack(err);
        process.exit(1);
    }
}
export async function mainCli() {
    await registrarLoader();
    process.on('unhandledRejection', __tutanus_unhandledRejectionHandler);
    process.on('uncaughtException', (err) => {
        const mensagem = extrairMensagemErro(err);
        console.error(chalk.red(CliBinMensagens.excecaoNaoCapturada.replace('{mensagem}', mensagem)));
        logErroStack(err);
        if (!process.env.VITEST)
            sair(ExitCode.Critical);
    });
    let memoria;
    try {
        memoria = await getDefaultMemory();
    }
    catch (err) {
        log.debug(`Erro ao carregar memória: ${err instanceof Error ? err.message : String(err)}`);
    }
    try {
        await carregarConfigProducao();
        const versionNumber = await getVersion();
        program.version(versionNumber);
        await inicializarConfigDinamica();
    }
    catch (err) {
        log.debug(`Erro na inicialização dinâmica: ${err instanceof Error ? err.message : String(err)}`);
    }
    try {
        const { inicializarFormattersBuiltin } = await import('../core/formatters/index.js');
        inicializarFormattersBuiltin();
    }
    catch (err) {
        log.debug(`Erro ao inicializar formatadores: ${err instanceof Error ? err.message : String(err)}`);
    }
    registrarComandos(program, ocorrencia => aplicarFlagsGlobais(ocorrencia));
    program.addCommand(comandoPerf());
    const argv = process.argv.slice(2);
    if (argv.includes('--historico')) {
        if (memoria) {
            const resumo = memoria.getSummary();
            console.log(chalk.cyan(CliBinMensagens.resumoConversa.titulo));
            console.log(CliBinMensagens.resumoConversa.total.replace('{total}', String(resumo.totalMessages)));
            console.log(CliBinMensagens.resumoConversa.usuario.replace('{total}', String(resumo.userMessages)));
            console.log(CliBinMensagens.resumoConversa.tutanus.replace('{total}', String(resumo.assistantMessages)));
            if (resumo.firstMessage)
                console.log(CliBinMensagens.resumoConversa.primeira.replace('{mensagem}', resumo.firstMessage));
            if (resumo.lastMessage)
                console.log(CliBinMensagens.resumoConversa.ultima.replace('{mensagem}', resumo.lastMessage));
            console.log('');
        }
        else {
            console.log(chalk.yellow(CliBinMensagens.historicoIndisponivel));
        }
        return;
    }
    if (argv.includes('--limpar-historico')) {
        if (memoria)
            await memoria.clear();
        console.log(chalk.green(CliBinMensagens.historicoLimpo));
        return;
    }
    try {
        await memoria?.addMessage({
            role: 'user',
            content: `Execução CLI: ${argv.join(' ') || '(sem argumentos)'}`,
            timestamp: new Date().toISOString()
        });
    }
    catch (err) {
        log.debug(`Erro ao registrar histórico: ${err instanceof Error ? err.message : String(err)}`);
    }
    program.exitOverride((err) => {
        const code = err?.code || '';
        const isSaidaNormal = code === 'commander.help' || code === 'commander.helpDisplayed' || code === 'commander.version';
        if (isSaidaNormal) {
            sair(ExitCode.Ok);
            return;
        }
        const isUsoInvalido = code === 'commander.unknownCommand' || code === 'commander.unknownOption' || code === 'commander.missingArgument' || code === 'commander.optionMissingArgument' || code === 'commander.missingMandatoryOptionValue' || code === 'commander.invalidArgument';
        if (isUsoInvalido) {
            console.error(chalk.red(`${ICONES_NIVEL.erro} ${err.message}`));
            sair(ExitCode.InvalidUsage);
            return;
        }
        throw err;
    });
    await program.parseAsync(process.argv);
}
const resolvedArgv1 = process.argv[1] ? pathToFileURL(realpathSync(process.argv[1])).href : '';
const isMain = import.meta.url === resolvedArgv1 || process.argv[1] && (process.argv[1].endsWith('/bin/index.js') || process.argv[1].endsWith('/bin/index.ts'));
if (isMain) {
    mainCli().catch(err => {
        const mensagem = extrairMensagemErro(err);
        console.error(chalk.red(`${ICONES_NIVEL.erro} ${mensagem}`));
        logErroStack(err);
        if (!process.env.VITEST)
            process.exit(1);
    });
}
//# sourceMappingURL=index.js.map