/**
 * ZinTrust CLI - Main Entry Point (hashbang-free)
 *
 * This module contains the CLI implementation without a hashbang so that it can
 * be imported by other bin shortcuts (zin/z/zt) without parse errors.
 */
import { Logger } from '../src/config/logger.js';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const loadPackageVersionFast = () => {
    try {
        const here = path.dirname(fileURLToPath(import.meta.url));
        const packagePath = path.join(here, '../package.json');
        const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
        return typeof packageJson.version === 'string' ? packageJson.version : '0.0.0';
    }
    catch {
        return '0.0.0';
    }
};
const stripLeadingScriptArg = (rawArgs) => {
    if (rawArgs.length === 0)
        return rawArgs;
    const first = rawArgs[0];
    const looksLikeScript = typeof first === 'string' && (first.endsWith('.ts') || first.endsWith('.js'));
    return looksLikeScript ? rawArgs.slice(1) : rawArgs;
};
const getArgsFromProcess = () => {
    const rawArgs = process.argv.slice(2);
    return { rawArgs, args: stripLeadingScriptArg(rawArgs) };
};
const isVersionRequest = (args) => {
    return args.includes('-v') || args.includes('--version');
};
const printFancyVersion = (version) => {
    const framework = 'ZinTrust Framework';
    const bannerWidth = 46;
    const env = (process.env['NODE_ENV'] ?? 'development').toString();
    const db = (process.env['DB_CONNECTION'] ?? 'sqlite').toString();
    // Keep this dependency-free and fast; version flags should return instantly.
    // (No logger, no config boot, no CLI registration.)
    console.log('┌' + '─'.repeat(bannerWidth) + '┐');
    console.log(`│ Framework: ${framework.padEnd(bannerWidth - 11)}│`);
    console.log(`│ Version:   ${version.padEnd(bannerWidth - 11)}│`);
    console.log(`│ Env:       ${env.padEnd(bannerWidth - 11)}│`);
    console.log(`│ Database:  ${db.padEnd(bannerWidth - 11)}│`);
    console.log('└' + '─'.repeat(bannerWidth) + '┘');
    console.log();
};
const shouldDebugArgs = (rawArgs) => {
    return process.env['ZINTRUST_CLI_DEBUG_ARGS'] === '1' && rawArgs.includes('--verbose');
};
const normalizeProxyTargetArgs = (args) => {
    if (args.length < 2 || args[0] !== 'proxy')
        return args;
    const target = args[1];
    if (!target || target.startsWith('-') || target.includes(':'))
        return args;
    const normalized = target.trim().toLowerCase();
    const aliases = {
        redis: 'redis',
        red: 'red',
        smtp: 'smtp',
        mysql: 'mysql',
        postgres: 'postgres',
        mongodb: 'mongodb',
        sqlserver: 'sqlserver',
    };
    const mappedTarget = aliases[normalized];
    if (!mappedTarget)
        return args;
    return [`proxy:${mappedTarget}`, ...args.slice(2)];
};
const handleCliFatal = async (error, context) => {
    try {
        Logger.error(context, error);
    }
    catch {
        // best-effort logging
    }
    try {
        const { ErrorHandler } = await import('../src/cli/ErrorHandler.js');
        ErrorHandler.handle(error);
    }
    catch {
        // best-effort error handling
    }
    process.exit(1);
};
export async function run() {
    try {
        // Fast path: print version and exit without bootstrapping the CLI.
        // This keeps `zin -v` / `zin --version` snappy and avoids any debug output.
        const { rawArgs: _rawArgs0, args: args0 } = getArgsFromProcess();
        if (isVersionRequest(args0)) {
            printFancyVersion(loadPackageVersionFast());
            return;
        }
        const { EnvFileLoader } = await import('../src/cli/utils/EnvFileLoader.js');
        EnvFileLoader.ensureLoaded();
        // Auto-load install-only CLI extension packages that self-register commands.
        let optionalCliExtensions;
        let optionalCliStatuses = [];
        try {
            ({ OptionalCliExtensions: optionalCliExtensions } =
                await import('../src/cli/OptionalCliExtensions.js'));
            optionalCliStatuses = await optionalCliExtensions.loadForArgs(args0);
        }
        catch {
            // best-effort; missing optional extensions must not block the CLI
        }
        const missingOptionalExtension = optionalCliExtensions?.findMissingExtensionForArgs(args0, optionalCliStatuses);
        if (missingOptionalExtension !== undefined) {
            const { ErrorFactory } = await import('../src/exceptions/ZintrustError.js');
            throw ErrorFactory.createCliError(optionalCliExtensions?.getMissingExtensionMessage(missingOptionalExtension) ??
                `Missing optional CLI package: ${missingOptionalExtension.packageName}`);
        }
        // Ensure project-installed adapters/drivers are registered for CLI commands.
        // (This is driven by src/zintrust.plugins.ts generated by `zin plugin install`.)
        try {
            const { PluginAutoImports } = await import('../src/runtime/PluginAutoImports.js');
            const runtimeImportMode = process.env['DOCKER_WORKER'] === 'true' ? 'worker' : 'base';
            const officialImports = await PluginAutoImports.tryImportRuntimeAutoImports(runtimeImportMode);
            if (!officialImports.ok) {
                Logger.warn('Official plugin auto-imports failed:', officialImports.errorMessage);
            }
            const projectImports = await PluginAutoImports.tryImportProjectAutoImports();
            if (!projectImports.ok && projectImports.reason !== 'not-found') {
                Logger.warn('Project plugin auto-imports failed:', projectImports.errorMessage);
            }
        }
        catch {
            // best-effort; CLI should still run even if plugins file is missing
        }
        const { CLI } = await import('../src/cli/CLI.js');
        const cli = CLI.create();
        // When executing via tsx (e.g. `npx tsx bin/zin.ts ...`), the script path can
        // appear as the first element of `process.argv.slice(2)`. Commander expects
        // args to start at the command name, so we strip a leading script path if present.
        const { rawArgs, args } = getArgsFromProcess();
        if (shouldDebugArgs(rawArgs)) {
            try {
                process.stderr.write(`[zintrust-cli] process.argv=${JSON.stringify(process.argv)}\n`);
                process.stderr.write(`[zintrust-cli] rawArgs=${JSON.stringify(rawArgs)}\n`);
            }
            catch {
                // ignore
            }
        }
        await cli.run(normalizeProxyTargetArgs(args));
    }
    catch (error) {
        await handleCliFatal(error, 'CLI execution failed');
    }
}
