/**
 * Simulate Command
 * Internal dev tool that generates a simulated ZinTrust app under ./simulate/
 * IMPORTANT: this uses the same ProjectScaffolder as `zin new`.
 * Usage: zin -sim my-blog
 */
import { ProjectScaffolder } from '../scaffolding/ProjectScaffolder.js';
import { DistPackager } from '../utils/DistPackager.js';
import { Logger } from '../../config/logger.js';
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
import fs from '../../node-singletons/fs.js';
import * as path from '../../node-singletons/path.js';
import chalk from 'chalk';
import { Command } from 'commander';
const rewriteSimulatedAppDependencyToDist = (appPath, distPath) => {
    const packageJsonPath = path.join(appPath, 'package.json');
    if (!fs.existsSync(packageJsonPath)) {
        throw ErrorFactory.createCliError(`Missing simulated app package.json at: ${packageJsonPath}`);
    }
    const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
    const dependencies = { ...pkg.dependencies };
    dependencies['@zintrust/core'] = `file:${distPath}`;
    const nextPkg = {
        ...pkg,
        dependencies,
    };
    fs.writeFileSync(packageJsonPath, JSON.stringify(nextPkg, null, 2) + '\n');
};
/**
 * SimulateCommand - Generate simulated apps for testing
 */
export const SimulateCommand = {
    name: 'simulate',
    description: '[INTERNAL] Generate simulated ZinTrust app for testing new developer experience',
    getCommand() {
        const command = new Command('simulate')
            .alias('-sim')
            .alias('--sim')
            .description('[INTERNAL DEV] Create a simulated ZinTrust application in simulate/ folder')
            .argument('<name>', 'Name of the simulated app')
            .action(async (appName) => {
            try {
                const simulateBasePath = path.join(process.cwd(), 'simulate');
                if (!appName || appName.trim() === '') {
                    throw ErrorFactory.createValidationError('App name is required');
                }
                // Delegate validation + file generation to the same scaffolder used by `zin new`.
                Logger.info(`Creating simulated app via ProjectScaffolder: ${chalk.cyan(appName)}`);
                const result = await ProjectScaffolder.scaffold(simulateBasePath, {
                    name: appName,
                    template: 'basic',
                    database: 'sqlite',
                    author: 'Internal',
                    description: `Simulated ZinTrust app - ${appName}`,
                });
                if (!result.success) {
                    throw ErrorFactory.createCliError(result.message, result.error);
                }
                const appPath = path.join(simulateBasePath, appName);
                // For simulate apps only: install the locally-built framework from dist/
                // so the dev experience matches "fresh install" of the current build output.
                const distPath = path.join(process.cwd(), 'dist');
                DistPackager.prepare(distPath, process.cwd());
                rewriteSimulatedAppDependencyToDist(appPath, distPath);
                Logger.info('✅ Simulated app created successfully!');
                Logger.info(`📁 Location: ${chalk.cyan(appPath)}`);
                Logger.info(`\n${chalk.bold('Next steps:')}`);
                Logger.info(`  cd ${path.relative(process.cwd(), appPath)}`);
                Logger.info('  npm install');
                Logger.info('  zin start');
            }
            catch (error) {
                Logger.error('Failed to create simulated app', error);
                process.exit(1);
            }
        });
        return command;
    },
};
