"use strict";
/*
 * SomonScript CLI
 * Copyright (c) 2025 LindenTech IT Consulting
 *
 * Licensed under the MIT License. See the LICENSE file for details.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createProgram = exports.cliRuntime = exports.compileFile = void 0;
const node_child_process_1 = require("node:child_process");
const commander_1 = require("commander");
const chokidar_1 = __importDefault(require("chokidar"));
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const node_module_1 = require("node:module");
const production_validator_1 = require("../production-validator");
const i18n_1 = require("./i18n");
// Read package.json at runtime to avoid import attribute issues
function findPackageJson() {
    let currentDir = __dirname;
    while (currentDir !== path.dirname(currentDir)) {
        const packagePath = path.join(currentDir, 'package.json');
        if (fs.existsSync(packagePath)) {
            return JSON.parse(fs.readFileSync(packagePath, 'utf8'));
        }
        currentDir = path.dirname(currentDir);
    }
    // Fallback for test environments - use deterministic path resolution
    // Instead of process.cwd(), use relative paths from __dirname
    const fallbackPath = path.resolve(__dirname, '..', '..', 'package.json');
    if (fs.existsSync(fallbackPath)) {
        return JSON.parse(fs.readFileSync(fallbackPath, 'utf8'));
    }
    throw new Error('package.json not found');
}
const pkg = findPackageJson();
let tsRuntimeRegistered = false;
const localRequire = (0, node_module_1.createRequire)(__filename);
const compiledCompilerModuleId = '../compiler';
const sourceCompilerModuleId = '../../src/compiler.ts';
const compiledConfigModuleId = '../config';
const sourceConfigModuleId = '../../src/config.ts';
const { compile } = loadCompiler();
const { loadConfig, ConfigError } = loadConfigModule();
function isConfigError(error) {
    return error instanceof ConfigError;
}
function logConfigError(error) {
    console.error('Configuration error:');
    console.error(`  ${error.message}`);
    if (error.details.length > 0) {
        for (const detail of error.details) {
            console.error(`  ${detail.path}: ${detail.message}`);
        }
    }
}
function handleCliFailure(error, fallbackPrefix) {
    if (isConfigError(error)) {
        logConfigError(error);
    }
    else {
        console.error(fallbackPrefix, error instanceof Error ? error.message : error);
    }
    if (!process.exitCode || process.exitCode === 0) {
        process.exitCode = 1;
    }
}
/**
 * Validate production environment requirements
 * Implements AGENTS.md principle: "Fail fast, fail clearly"
 *
 * @param outputPath - Output path to validate write permissions
 * @param requiredPaths - Optional array of required input paths
 */
function validateProductionEnvironment(outputPath, requiredPaths) {
    const validator = new production_validator_1.ProductionValidator();
    validator.validate({
        isProduction: true,
        outputPath,
        requiredPaths,
    });
}
async function executeBundleCommand(input, options) {
    try {
        const baseDir = path.dirname(path.resolve(input));
        const config = loadConfig(baseDir);
        const isProduction = options.production || process.env.NODE_ENV === 'production';
        // Validate production environment if --production flag is set
        if (isProduction) {
            const outputPath = options.output || input.replace(/\.som$/, '.bundle.js');
            try {
                validateProductionEnvironment(outputPath, [input]);
            }
            catch (error) {
                handleCliFailure(error, 'Production validation failed:');
                throw error; // Re-throw to exit bundle command
            }
        }
        const moduleSystem = await createModuleSystem(baseDir, config, isProduction);
        // Install signal handlers for graceful shutdown in production
        if (isProduction) {
            await installSignalHandlers(moduleSystem);
        }
        const bundleOptions = createBundleOptions(input, options, config, baseDir);
        await performBundling(moduleSystem, bundleOptions, input);
    }
    catch (error) {
        handleCliFailure(error, 'Bundle error:');
    }
}
async function createModuleSystem(baseDir, config, isProduction = false) {
    const { ModuleSystem } = await Promise.resolve().then(() => __importStar(require('../module-system')));
    return new ModuleSystem({
        resolution: {
            baseUrl: baseDir,
            ...config.moduleSystem?.resolution,
        },
        loading: config.moduleSystem?.loading
            ? {
                ...config.moduleSystem.loading,
                encoding: config.moduleSystem.loading.encoding,
            }
            : undefined,
        compilation: config.moduleSystem?.compilation,
        // Enforce production features when in production mode
        metrics: isProduction || config.moduleSystem?.metrics,
        circuitBreakers: isProduction || config.moduleSystem?.circuitBreakers,
        logger: isProduction || config.moduleSystem?.logger,
        managementServer: isProduction || config.moduleSystem?.managementServer,
        managementPort: config.moduleSystem?.managementPort,
        // Production resource limits and timeouts
        resourceLimits: isProduction
            ? {
                maxMemoryBytes: config.moduleSystem?.resourceLimits?.maxMemoryBytes,
                maxFileHandles: config.moduleSystem?.resourceLimits?.maxFileHandles ?? 1000,
                maxCachedModules: config.moduleSystem?.resourceLimits?.maxCachedModules ?? 10000,
                checkInterval: config.moduleSystem?.resourceLimits?.checkInterval ?? 5000,
            }
            : config.moduleSystem?.resourceLimits,
        operationTimeout: isProduction
            ? (config.moduleSystem?.operationTimeout ?? 120000)
            : config.moduleSystem?.operationTimeout,
    });
}
/**
 * Install signal handlers for graceful shutdown
 * Ensures proper cleanup on SIGTERM, SIGINT, SIGHUP
 */
async function installSignalHandlers(moduleSystem) {
    const { SignalHandler } = await Promise.resolve().then(() => __importStar(require('../module-system')));
    const signalHandler = new SignalHandler({
        shutdownTimeout: 30000,
    });
    // Register module system shutdown
    signalHandler.register(async () => {
        await moduleSystem.shutdown();
    });
    signalHandler.install();
}
function createBundleOptions(input, options, config, _baseDir) {
    const formatValue = options.format ?? config.bundle?.format ?? 'commonjs';
    const requestedFormat = typeof formatValue === 'string' ? formatValue.toLowerCase() : 'commonjs';
    if (requestedFormat !== 'commonjs') {
        throw new Error(`SomonScript currently supports only the 'commonjs' bundle format. Received '${requestedFormat}'.`);
    }
    return {
        entryPoint: path.resolve(input),
        outputPath: options.output ?? config.bundle?.output,
        format: 'commonjs',
        minify: options.minify ?? config.bundle?.minify,
        sourceMaps: options.sourceMap ?? config.bundle?.sourceMaps,
        inlineSources: options.inlineSources ?? config.bundle?.inlineSources,
        externals: options.externals ? options.externals.split(',') : config.bundle?.externals,
    };
}
async function performBundling(moduleSystem, bundleOptions, input) {
    console.log(`📦 Bundling ${input}...`);
    const bundle = await moduleSystem.bundle(bundleOptions);
    const outputPath = getBundleOutputPath(bundleOptions, input);
    fs.mkdirSync(path.dirname(outputPath), { recursive: true });
    let outputCode = bundle.code;
    if (bundle.map) {
        const mapPath = `${outputPath}.map`;
        fs.writeFileSync(mapPath, bundle.map, 'utf8');
        outputCode = `${outputCode}\n//# sourceMappingURL=${path.basename(mapPath)}`;
        console.log(`🗺️ Source map created: ${mapPath}`);
    }
    fs.writeFileSync(outputPath, outputCode, 'utf8');
    console.log(`✅ Bundle created: ${outputPath}`);
    const stats = moduleSystem.getStatistics();
    console.log(`📊 Bundled ${stats.totalModules} modules`);
}
function getBundleOutputPath(bundleOptions, input) {
    if (bundleOptions.outputPath) {
        return path.isAbsolute(bundleOptions.outputPath)
            ? bundleOptions.outputPath
            : path.resolve(path.dirname(path.resolve(input)), bundleOptions.outputPath);
    }
    return input.replace(/\.som$/, '.bundle.js');
}
function mergeOptions(input, options) {
    const config = loadConfig(path.dirname(path.resolve(input)));
    const merged = { ...config.compilerOptions, ...options };
    // Handle negation flags - they override positive flags
    if (options.noSourceMap) {
        merged.sourceMap = false;
    }
    if (options.noMinify) {
        merged.minify = false;
    }
    // Set default target if not specified
    if (!merged.target) {
        merged.target = 'es2020';
    }
    return merged;
}
function compileFile(input, options) {
    try {
        if (!fs.existsSync(input)) {
            const message = (0, i18n_1.t)().commands.compile.messages.fileNotFound(input);
            console.error(message);
            process.exitCode = 1;
            return { code: '', errors: [message], warnings: [] };
        }
        const source = fs.readFileSync(input, 'utf-8');
        const result = compile(source, {
            target: options.target,
            sourceMap: options.sourceMap,
            minify: options.minify,
            typeCheck: !options.noTypeCheck,
            strict: options.strict,
        });
        if (result.errors.length > 0) {
            console.error((0, i18n_1.t)().commands.compile.messages.compilationErrors);
            for (const error of result.errors) {
                console.error(`  ${error}`);
            }
            process.exitCode = 1;
        }
        if (result.warnings.length > 0) {
            console.warn((0, i18n_1.t)().commands.compile.messages.warnings);
            for (const warning of result.warnings) {
                console.warn(`  ${warning}`);
            }
        }
        return result;
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        console.error('Error:', message);
        process.exitCode = 1;
        return { code: '', errors: [message], warnings: [] };
    }
}
exports.compileFile = compileFile;
function resolveForwardedArgv(command, input) {
    const parentArgs = command.parent?.args ?? [];
    return parentArgs.length > 0 ? [...parentArgs] : [command.name(), input];
}
function createRunOutputPath(input, sourceDir) {
    const baseName = path.basename(input);
    const withoutExtension = baseName.includes('.') ? baseName.replace(/\.[^.]+$/, '') : baseName;
    const safeBase = withoutExtension || 'somon-script';
    const uniqueSuffix = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`;
    return path.join(sourceDir, `${safeBase}.somon-run-${uniqueSuffix}.js`);
}
exports.cliRuntime = {
    executeCompiledFile(filePath, forwardedArgv = [], options = {}) {
        return (0, node_child_process_1.spawnSync)(process.execPath, [filePath, ...forwardedArgv], {
            stdio: 'inherit',
            env: process.env,
            cwd: options.cwd,
        });
    },
};
/**
 * Display module statistics
 */
function displayModuleStatistics(moduleSystem) {
    const stats = moduleSystem.getStatistics();
    console.log('\n📊 Module Statistics:');
    console.log(`  Total modules: ${stats.totalModules}`);
    console.log(`  Total dependencies: ${stats.totalDependencies}`);
    console.log(`  Average dependencies per module: ${stats.averageDependencies.toFixed(2)}`);
    console.log(`  Maximum dependency depth: ${stats.maxDependencyDepth}`);
    console.log(`  Circular dependencies: ${stats.circularDependencies}`);
}
/**
 * Display dependency graph
 */
function displayDependencyGraph(moduleSystem, baseDir) {
    const graph = moduleSystem.getDependencyGraph();
    console.log('\n🕸️  Dependency Graph:');
    for (const [moduleId, deps] of graph) {
        const relativePath = path.relative(baseDir, moduleId);
        console.log(`  ${relativePath}:`);
        for (const dep of deps) {
            console.log(`    └── ${dep}`);
        }
    }
}
/**
 * Display circular dependency validation results
 */
function displayCircularDependencies(moduleSystem) {
    const validation = moduleSystem.validate();
    if (validation.isValid) {
        console.log('\n✅ No circular dependencies found');
    }
    else {
        console.log('\n❌ Issues found:');
        for (const error of validation.errors) {
            console.log(`  • ${error}`);
        }
    }
}
function createProgram() {
    const program = new commander_1.Command();
    // Add global --lang option
    program
        .name('somon')
        .description((0, i18n_1.t)().commands.somon.description)
        .version(pkg.version, '-V, --version', (0, i18n_1.t)().common.version)
        .option('--lang <language>', 'Set interface language (en, tj, ru)', (value) => {
        if (value === 'en' || value === 'tj' || value === 'ru') {
            i18n_1.i18n.setLanguage(value);
        }
        return value;
    })
        .helpOption('-h, --help', (0, i18n_1.t)().common.help);
    program
        .command((0, i18n_1.t)().commands.compile.name)
        .alias((0, i18n_1.t)().commands.compile.alias)
        .description((0, i18n_1.t)().commands.compile.description)
        .usage((0, i18n_1.t)().commands.compile.usage)
        .argument('<input>', (0, i18n_1.t)().commands.compile.args.input)
        .option('-o, --output <file>', (0, i18n_1.t)().commands.compile.options.output)
        .option('--out-dir <dir>', (0, i18n_1.t)().commands.compile.options.outDir)
        .option('--target <target>', (0, i18n_1.t)().commands.compile.options.target)
        .option('--source-map', (0, i18n_1.t)().commands.compile.options.sourceMap)
        .option('--no-source-map', (0, i18n_1.t)().commands.compile.options.noSourceMap)
        .option('--minify', (0, i18n_1.t)().commands.compile.options.minify)
        .option('--no-minify', (0, i18n_1.t)().commands.compile.options.noMinify)
        .option('--no-type-check', (0, i18n_1.t)().commands.compile.options.noTypeCheck)
        .option('--strict', (0, i18n_1.t)().commands.compile.options.strict)
        .option('-w, --watch', (0, i18n_1.t)().commands.compile.options.watch)
        .option('--production', (0, i18n_1.t)().commands.compile.options.production)
        .action((input, options) => {
        try {
            let merged;
            try {
                merged = mergeOptions(input, options);
            }
            catch (error) {
                handleCliFailure(error, 'Error:');
                return;
            }
            // Validate production environment if --production flag is set
            if (merged.production || process.env.NODE_ENV === 'production') {
                const baseDir = path.dirname(path.resolve(input));
                const outputFile = merged.output ||
                    (merged.outDir
                        ? path.join(path.resolve(baseDir, merged.outDir), path.basename(input).replace(/\.som$/, '.js'))
                        : input.replace(/\.som$/, '.js'));
                try {
                    validateProductionEnvironment(outputFile, [input]);
                }
                catch (error) {
                    handleCliFailure(error, 'Production validation failed:');
                    return;
                }
            }
            const shouldWatch = !!(merged.watch || merged.compileOnSave);
            const compileOnce = () => {
                try {
                    merged = mergeOptions(input, options);
                }
                catch (error) {
                    handleCliFailure(error, 'Error:');
                    return false;
                }
                const result = compileFile(input, merged);
                if (result.errors.length > 0)
                    return false;
                const baseDir = path.dirname(path.resolve(input));
                const outputFile = merged.output ||
                    (merged.outDir
                        ? path.join(path.resolve(baseDir, merged.outDir), path.basename(input).replace(/\.som$/, '.js'))
                        : input.replace(/\.som$/, '.js'));
                fs.mkdirSync(path.dirname(outputFile), { recursive: true });
                fs.writeFileSync(outputFile, result.code);
                console.log((0, i18n_1.t)().commands.compile.messages.compiled(input, outputFile));
                if (merged.sourceMap && result.sourceMap) {
                    const sourceMapFile = `${outputFile}.map`;
                    fs.writeFileSync(sourceMapFile, result.sourceMap);
                    console.log((0, i18n_1.t)().commands.compile.messages.sourceMapGenerated(sourceMapFile));
                }
                return true;
            };
            const initialSuccess = compileOnce();
            if (!initialSuccess && !shouldWatch) {
                return;
            }
            if (shouldWatch && process.env.NODE_ENV !== 'test') {
                console.log((0, i18n_1.t)().commands.compile.messages.watching(input));
                const absoluteInput = path.resolve(input);
                const watchTargets = new Set([
                    absoluteInput,
                    path.resolve(path.dirname(absoluteInput), 'somon.config.json'),
                ]);
                const watcher = chokidar_1.default.watch(Array.from(watchTargets), {
                    persistent: true,
                    ignoreInitial: true,
                    awaitWriteFinish: {
                        stabilityThreshold: 150,
                        pollInterval: 20,
                    },
                });
                let watcherClosed = false;
                // Install signal handlers for graceful shutdown in watch mode
                const gracefulShutdown = async (signal) => {
                    if (!watcherClosed) {
                        console.log(`\nReceived ${signal}, stopping watcher...`);
                        watcherClosed = true;
                        await watcher.close();
                        process.exit(0);
                    }
                };
                process.on('SIGTERM', () => void gracefulShutdown('SIGTERM'));
                process.on('SIGINT', () => void gracefulShutdown('SIGINT'));
                process.on('SIGHUP', () => void gracefulShutdown('SIGHUP'));
                const handleFileEvent = (eventType, changedPath) => {
                    const normalizedPath = path.resolve(changedPath);
                    if (normalizedPath === absoluteInput) {
                        if (eventType === 'unlink') {
                            console.warn(`Source file '${input}' was removed. Waiting for it to reappear...`);
                            return;
                        }
                        console.log((0, i18n_1.t)().commands.compile.messages.recompiling(input));
                        compileOnce();
                        return;
                    }
                    if (eventType === 'unlink') {
                        console.warn(`Configuration file '${path.basename(normalizedPath)}' was removed. Using previous options.`);
                        return;
                    }
                    console.log((0, i18n_1.t)().commands.compile.messages.configChanged(path.basename(normalizedPath)));
                    compileOnce();
                };
                watcher
                    .on('add', (changedPath) => handleFileEvent('add', changedPath))
                    .on('change', (changedPath) => handleFileEvent('change', changedPath))
                    .on('unlink', (changedPath) => handleFileEvent('unlink', changedPath))
                    .on('error', (error) => {
                    console.error('Watch error:', error instanceof Error ? error.message : String(error));
                });
                const cleanupWatcher = () => {
                    if (watcherClosed)
                        return;
                    watcherClosed = true;
                    watcher.close().catch((error) => {
                        console.error('Failed to close watcher:', error instanceof Error ? error.message : String(error));
                    });
                };
                const registerSignalHandler = (signal) => {
                    process.once(signal, () => {
                        cleanupWatcher();
                        process.exit(process.exitCode ?? 0);
                    });
                };
                registerSignalHandler('SIGINT');
                registerSignalHandler('SIGTERM');
                process.once('exit', cleanupWatcher);
            }
            else if (shouldWatch) {
                // In test environment, just log the message without actually watching
                console.log(`Watching '${input}' for changes...`);
            }
        }
        catch (error) {
            handleCliFailure(error, 'Error:');
            return;
        }
    });
    program
        .command('run')
        .alias('r')
        .description('Compile and run SomonScript file')
        .usage('[input] [options]')
        .argument('<input>', 'Input .som file')
        .option('--target <target>', 'Compilation target')
        .option('--source-map', 'Generate source maps')
        .option('--no-source-map', 'Disable source maps')
        .option('--minify', 'Minify output')
        .option('--no-minify', 'Disable minification')
        .option('--no-type-check', 'Disable type checking')
        .option('--strict', 'Enable strict type checking')
        .option('--production', 'Enable production mode with strict validation')
        .action(async (input, options, command) => {
        const cleanupTargets = [];
        try {
            const baseDir = path.dirname(path.resolve(input));
            const config = loadConfig(baseDir);
            const isProduction = options.production || process.env.NODE_ENV === 'production';
            // Validate production environment if --production flag is set
            if (isProduction) {
                const compiledFilePath = createRunOutputPath(input, baseDir);
                try {
                    validateProductionEnvironment(compiledFilePath, [input]);
                }
                catch (error) {
                    handleCliFailure(error, 'Production validation failed:');
                    return;
                }
            }
            // Create module system and bundle the file with all dependencies
            const moduleSystem = await createModuleSystem(baseDir, config, isProduction);
            // Create bundle options for temporary output
            const compiledFilePath = createRunOutputPath(input, baseDir);
            const bundleOptions = {
                entryPoint: path.resolve(input),
                outputPath: compiledFilePath,
                format: 'commonjs',
                minify: options.minify ?? config.bundle?.minify,
                sourceMaps: options.sourceMap ?? config.bundle?.sourceMaps,
                inlineSources: false,
                externals: config.bundle?.externals,
            };
            // Bundle the file and all its dependencies
            const bundle = await moduleSystem.bundle(bundleOptions);
            // Write the bundled code to temporary file
            fs.writeFileSync(compiledFilePath, bundle.code, 'utf8');
            cleanupTargets.push(compiledFilePath);
            // Write source map if enabled
            if (options.sourceMap && bundle.map) {
                const mapPath = `${compiledFilePath}.map`;
                fs.writeFileSync(mapPath, bundle.map, 'utf8');
                cleanupTargets.push(mapPath);
            }
            // Execute the bundled file
            const child = exports.cliRuntime.executeCompiledFile(compiledFilePath, resolveForwardedArgv(command, input), { cwd: baseDir });
            if (child.error) {
                console.error('Failed to execute Node:', child.error.message ?? child.error);
                process.exitCode = 1;
            }
            else if (typeof child.status === 'number') {
                process.exitCode = child.status;
            }
            else if (typeof child.signal === 'string') {
                console.error(`Process terminated with signal ${child.signal}`);
                process.exitCode = 1;
            }
        }
        catch (error) {
            handleCliFailure(error, 'Error:');
            return;
        }
        finally {
            // Clean up temporary files
            for (const target of cleanupTargets) {
                try {
                    fs.rmSync(target, { force: true });
                }
                catch (cleanupError) {
                    console.warn('Warning: unable to clean temporary files:', cleanupError instanceof Error ? cleanupError.message : cleanupError);
                }
            }
        }
    });
    program
        .command('init')
        .description('Initialize a new SomonScript project')
        .argument('[name]', 'Project name', 'somon-project')
        .action((name) => {
        try {
            const projectDir = path.resolve(name);
            if (fs.existsSync(projectDir)) {
                console.error(`Error: Directory '${name}' already exists`);
                process.exitCode = 1;
                return;
            }
            // Create project directory
            fs.mkdirSync(projectDir, { recursive: true });
            // Create package.json
            const packageJson = {
                name,
                version: '0.1.0',
                description: 'A SomonScript project',
                main: 'dist/main.js',
                scripts: {
                    build: 'somon compile src/main.som -o dist/main.js',
                    dev: 'somon run src/main.som',
                },
                devDependencies: {
                    [pkg.name]: `^${pkg.version}`,
                },
            };
            fs.writeFileSync(path.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
            // Create src and dist directories
            fs.mkdirSync(path.join(projectDir, 'src'));
            fs.mkdirSync(path.join(projectDir, 'dist'));
            // Create default configuration
            const somonConfig = {
                compilerOptions: {
                    target: 'es2020',
                    sourceMap: false,
                    minify: false,
                    noTypeCheck: false,
                    strict: false,
                    outDir: 'dist',
                    watch: false,
                    compileOnSave: false,
                },
            };
            fs.writeFileSync(path.join(projectDir, 'somon.config.json'), JSON.stringify(somonConfig, null, 2));
            // Create main file
            const mainSom = `// SomonScript main file
функсия салом(): void {
    чоп.сабт("Салом, ҷаҳон!");
}

салом();
`;
            fs.writeFileSync(path.join(projectDir, 'src', 'main.som'), mainSom);
            console.log(`✅ Created SomonScript project '${name}'`);
            console.log(`\nNext steps:`);
            console.log(`  cd ${name}`);
            console.log(`  npm install`);
            console.log(`  npm run dev`);
        }
        catch (error) {
            console.error('Error:', error instanceof Error ? error.message : error);
            process.exit(1);
        }
    });
    // Bundle command
    program
        .command('bundle')
        .alias('b')
        .description('Bundle SomonScript modules into a single file')
        .usage('[input] [options]')
        .argument('<input>', 'Entry point file')
        .option('-o, --output <file>', 'Output file path')
        .option('-f, --format <format>', "Bundle format (only 'commonjs' is supported)", 'commonjs')
        .option('--minify', 'Minify the output')
        .option('--source-map', 'Generate source maps')
        .option('--inline-sources', 'Inline original sources into emitted source maps')
        .option('--externals <modules>', 'External modules (comma-separated)')
        .option('--production', 'Enable production mode with strict validation')
        .action(async (input, options) => {
        await executeBundleCommand(input, options);
    });
    // Module info command
    program
        .command('module-info')
        .alias('info')
        .description('Show module dependency information')
        .usage('[input] [options]')
        .argument('<input>', 'Entry point file')
        .option('--graph', 'Show dependency graph')
        .option('--stats', 'Show module statistics')
        .option('--circular', 'Check for circular dependencies')
        .action(async (input, options) => {
        try {
            const baseDir = path.dirname(path.resolve(input));
            const config = loadConfig(baseDir);
            const moduleSystem = await createModuleSystem(baseDir, config, false);
            console.log(`🔍 Analyzing ${input}...`);
            const resolvedInput = path.resolve(input);
            await moduleSystem.loadModule(resolvedInput, path.dirname(resolvedInput));
            if (options.stats) {
                displayModuleStatistics(moduleSystem);
            }
            if (options.graph) {
                displayDependencyGraph(moduleSystem, baseDir);
            }
            if (options.circular) {
                displayCircularDependencies(moduleSystem);
            }
        }
        catch (error) {
            console.error('Analysis error:', error instanceof Error ? error.message : error);
            process.exit(1);
        }
    });
    // Resolve command
    program
        .command('resolve')
        .description('Resolve a module specifier to its file path')
        .usage('<specifier> [options]')
        .argument('<specifier>', 'Module specifier to resolve')
        .option('-f, --from <file>', 'Resolve from this file (defaults to current directory)')
        .action(async (specifier, options) => {
        try {
            const { ModuleResolver } = await Promise.resolve().then(() => __importStar(require('../module-system')));
            // Use explicit path resolution instead of process.cwd()
            const fromFile = options.from ?? path.resolve('.');
            const resolver = new ModuleResolver({
                baseUrl: path.dirname(path.resolve(fromFile)),
            });
            const resolved = resolver.resolve(specifier, fromFile);
            console.log(`🎯 Resolved '${specifier}':`);
            console.log(`  Path: ${resolved.resolvedPath}`);
            console.log(`  Extension: ${resolved.extension}`);
            console.log(`  External: ${resolved.isExternalLibrary ? 'Yes' : 'No'}`);
            if (resolved.packageName) {
                console.log(`  Package: ${resolved.packageName}`);
            }
        }
        catch (error) {
            console.error('Resolve error:', error instanceof Error ? error.message : error);
            process.exit(1);
        }
    });
    // Serve command for management server
    program
        .command('serve')
        .description('Start the management server for health checks and metrics')
        .option('-p, --port <port>', 'Port to listen on', '8080')
        .option('-c, --config <file>', 'Path to configuration file')
        .option('--production', 'Enable production mode with all safety features')
        .option('--json', 'Use structured JSON logging')
        .action(async (_options) => {
        const { createServeCommand } = await Promise.resolve().then(() => __importStar(require('./serve')));
        const serveCommand = createServeCommand();
        await serveCommand.parseAsync([process.argv[0], process.argv[1], ...process.argv.slice(3)], {
            from: 'user',
        });
    });
    return program;
}
exports.createProgram = createProgram;
function loadCompiler() {
    try {
        return localRequire(compiledCompilerModuleId);
    }
    catch (error) {
        if (!isModuleNotFound(error)) {
            throw error;
        }
    }
    try {
        return localRequire('../compiler.js');
    }
    catch (error) {
        if (!isModuleNotFound(error)) {
            throw error;
        }
    }
    const ts = loadTypeScript();
    const compilerSourcePath = path.resolve(__dirname, '..', '..', 'src', 'compiler.ts');
    if (!fs.existsSync(compilerSourcePath)) {
        throw new Error("Compiler module not found. Run 'npm run build' before executing the CLI.");
    }
    registerRuntimeTsTranspiler(ts);
    return localRequire(sourceCompilerModuleId);
}
function loadConfigModule() {
    try {
        return localRequire(compiledConfigModuleId);
    }
    catch (error) {
        if (!isModuleNotFound(error)) {
            throw error;
        }
    }
    try {
        return localRequire('../config.js');
    }
    catch (error) {
        if (!isModuleNotFound(error)) {
            throw error;
        }
    }
    const ts = loadTypeScript();
    const configSourcePath = path.resolve(__dirname, '..', '..', 'src', 'config.ts');
    if (!fs.existsSync(configSourcePath)) {
        throw new Error("Config module not found. Run 'npm run build' before executing the CLI.");
    }
    registerRuntimeTsTranspiler(ts);
    return localRequire(sourceConfigModuleId);
}
function isModuleNotFound(error) {
    return error instanceof Error && error.code === 'MODULE_NOT_FOUND';
}
function loadTypeScript() {
    try {
        return require('typescript');
    }
    catch (error) {
        const message = error instanceof Error ? error.message : 'Unknown error loading TypeScript';
        throw new Error(`TypeScript runtime is required to execute the CLI without compiled artifacts. Please install dev dependencies. Original error: ${message}`);
    }
}
function registerRuntimeTsTranspiler(ts) {
    if (tsRuntimeRegistered || require.extensions['.ts']) {
        // Either we already registered our hook or another tool (e.g. ts-node) is handling .ts files.
        tsRuntimeRegistered = true;
        return;
    }
    require.extensions['.ts'] = (module, filename) => {
        const source = fs.readFileSync(filename, 'utf-8');
        const { outputText } = ts.transpileModule(source, {
            compilerOptions: {
                module: ts.ModuleKind.CommonJS,
                target: ts.ScriptTarget.ES2020,
                esModuleInterop: true,
                sourceMap: false,
            },
            fileName: filename,
        });
        module._compile(outputText, filename);
    };
    tsRuntimeRegistered = true;
}
//# sourceMappingURL=program.js.map