"use strict";
/**
 * Generate command
 * Generates code from a workflow file with enhanced error handling
 */
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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateCommand = generateCommand;
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const workflow_parser_1 = require("../../parser/workflow-parser");
const generation_orchestrator_1 = require("../../generators/generation-orchestrator");
const error_handler_1 = require("../../utils/error-handler");
const output = __importStar(require("../output"));
require("../../generators"); // Ensure generators are registered
async function generateCommand(workflowPath, options) {
    const spinner = output.spinner('');
    try {
        // Banner
        output.banner('Bangstack Code Generator', 'Transforming workflows into production-ready code');
        // Resolve workflow path
        const absoluteWorkflowPath = path.resolve(process.cwd(), workflowPath);
        // Check if workflow file exists
        if (!fs.existsSync(absoluteWorkflowPath)) {
            output.errorWithSuggestions(`Workflow file not found: ${workflowPath}`, [
                `Check if the path is correct: ${output.code(workflowPath)}`,
                `Run ${output.code('bang init')} to create a new workflow`,
                `See example workflows: ${output.code('ls examples/')}`,
            ]);
            process.exit(1);
        }
        // Parse workflow
        spinner.text = 'Parsing workflow...';
        spinner.start();
        const parser = new workflow_parser_1.WorkflowParser();
        const parseResult = await parser.parseFile(absoluteWorkflowPath);
        spinner.succeed('Workflow parsed successfully');
        // Show workflow info
        output.blank();
        output.table([
            ['Workflow', output.bold(parseResult.workflow.workflow.name)],
            ['Version', parseResult.workflow.workflow.version],
            ['Stack Components', Object.keys(parseResult.workflow.stack).join(', ')],
        ]);
        if (parseResult.extendedWorkflow?.models) {
            output.info(`Extended schema detected with ${Object.keys(parseResult.extendedWorkflow.models).length} models`);
        }
        // Generate code using orchestrator with error handling
        const outputDir = path.resolve(process.cwd(), options.output);
        // Check if resuming from checkpoint
        if (options.resume) {
            spinner.text = 'Checking for resume point...';
            spinner.start();
            spinner.succeed('Found checkpoint, resuming generation');
        }
        output.blank();
        output.header('Generating Code');
        spinner.text = `Generating ${options.dryRun ? '(dry run)' : ''}...`;
        spinner.start();
        const orchestrator = new generation_orchestrator_1.GenerationOrchestrator();
        let lastProgressMessage = '';
        const result = await orchestrator.generate(parseResult.workflow, {
            outputDirectory: outputDir,
            dryRun: options.dryRun,
            verbose: options.verbose,
            workflowFilePath: absoluteWorkflowPath,
            extendedWorkflow: parseResult.extendedWorkflow,
            resume: options.resume,
            noCheckpoint: options.noCheckpoint,
            autoRollback: true,
            retryTransient: !options.noRetry,
            maxRetries: options.maxRetries || 3,
            onProgress: (progress) => {
                // Update spinner with current progress
                const fileName = progress.file ? output.path(path.basename(progress.file)) : '';
                const message = `${progress.stage} (${progress.current}/${progress.total}) ${fileName}`;
                // Only update if message changed (to avoid flicker)
                if (message !== lastProgressMessage) {
                    spinner.text = message;
                    lastProgressMessage = message;
                }
                // Show detailed progress in verbose mode
                if (options.verbose && progress.message) {
                    spinner.stop();
                    output.info(progress.message);
                    spinner.start();
                }
            },
        });
        spinner.succeed(`Generated ${result.files.length} files`);
        // Show retry information if any
        if (result.retries && result.retries > 0) {
            output.warning(`Recovered from ${result.retries} transient failure(s)`);
        }
        // Show rollback information if any
        if (result.rolledBack) {
            output.warning('Changes were rolled back due to failure');
        }
        // Show summary
        output.blank();
        output.header('Generation Summary');
        output.success(`Files generated: ${result.files.length}`);
        if (result.warnings.length > 0) {
            output.warning(`Warnings: ${result.warnings.length}`);
            if (options.verbose) {
                output.list(result.warnings, 'yellow');
            }
        }
        // Show checkpoint status if available
        if (result.checkpoint) {
            output.blank();
            output.subheader('Checkpoint Status');
            output.table([
                ['Stage', result.checkpoint.stage],
                ['Progress', `${result.checkpoint.percentage}%`],
            ]);
            if (result.checkpoint.canResume) {
                output.info('Can resume from this checkpoint if generation is interrupted');
            }
        }
        if (result.errors.length > 0) {
            output.blank();
            output.error(`Errors: ${result.errors.length}`);
            result.errors.forEach(e => {
                // Errors are already formatted by ErrorFactory
                console.log(e);
            });
            process.exit(1);
        }
        // Group files by component
        if (options.verbose) {
            output.blank();
            output.header('Generated Files');
            const filesByComponent = {};
            for (const file of result.files) {
                const relativePath = path.relative(outputDir, file.path);
                const parts = relativePath.split(path.sep);
                const component = parts[0] || 'root';
                if (!filesByComponent[component]) {
                    filesByComponent[component] = [];
                }
                filesByComponent[component].push(relativePath);
            }
            for (const [component, files] of Object.entries(filesByComponent)) {
                output.subheader(component);
                output.list(files, 'gray');
            }
        }
        // Show next steps
        if (!options.dryRun && result.files.length > 0) {
            output.blank();
            output.header('Next Steps');
            // Group by component and show install commands
            const components = [...new Set(result.files.map(f => {
                    const relativePath = path.relative(outputDir, f.path);
                    return relativePath.split(path.sep)[0];
                }))];
            const steps = [];
            for (const component of components) {
                const componentPath = path.join(outputDir, component);
                const hasPkg = fs.existsSync(path.join(componentPath, 'package.json'));
                if (hasPkg) {
                    steps.push(`cd ${output.path(path.relative(process.cwd(), componentPath))} && npm install`);
                }
            }
            if (steps.length > 0) {
                output.list(steps, 'blue');
            }
            else {
                output.info('No additional setup required!');
            }
        }
    }
    catch (error) {
        spinner.fail('Generation failed');
        output.blank();
        // Handle EnhancedError with formatted output
        if (error instanceof error_handler_1.EnhancedError) {
            console.error(error.format());
            // Show recovery suggestions
            if (error.isRecoverable()) {
                const recovery = error.getAutomatedRecovery();
                if (recovery) {
                    output.blank();
                    output.info('Automated recovery available:');
                    console.log('   ' + output.dim(recovery.description));
                    if (recovery.command) {
                        console.log('   Run: ' + output.code(recovery.command));
                    }
                }
            }
        }
        else if (error instanceof Error) {
            output.error(error.message);
            if (options.verbose && error.stack) {
                output.blank();
                console.error(output.dim(error.stack));
            }
        }
        else {
            output.error(String(error));
        }
        // Show helpful suggestions
        output.blank();
        output.errorWithSuggestions('Generation failed', [
            `Resume from last checkpoint: ${output.code(`bang generate ${workflowPath} --resume`)}`,
            `Run with verbose output: ${output.code(`bang generate ${workflowPath} --verbose`)}`,
            `Check the workflow syntax: ${output.code(`bang validate ${workflowPath}`)}`,
        ]);
        process.exit(1);
    }
}
//# sourceMappingURL=generate.js.map