"use strict";
/**
 * Verify Command
 * Validates workflow and checks for dependency mismatches without generating code
 */
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.verifyCommand = verifyCommand;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const yaml = __importStar(require("js-yaml"));
const workflow_engine_1 = require("../../engine/workflow-engine");
const dependency_analyzer_1 = require("../../generators/dependency-analyzer");
async function verifyCommand(workflowPath, options) {
    console.log('\n📊 Verification Report\n');
    try {
        // Read workflow file
        const workflowContent = fs.readFileSync(workflowPath, 'utf-8');
        const workflow = yaml.load(workflowContent);
        console.log(`Workflow: ${workflow.workflow.name}`);
        console.log(`Version: ${workflow.workflow.version}`);
        console.log();
        // Validate workflow
        const engine = new workflow_engine_1.WorkflowEngine();
        const validation = engine.validate(workflow);
        if (!validation.valid) {
            console.error('❌ Workflow Validation Failed:\n');
            validation.errors.forEach(error => console.error(`   ${error}`));
            process.exit(1);
        }
        if (validation.warnings.length > 0) {
            console.log('⚠️  Validation Warnings:\n');
            validation.warnings.forEach(warning => console.log(`   ${warning}`));
            console.log();
        }
        // Check for existing manifest
        const outputDir = options.output || process.cwd();
        const manifestPath = path.join(outputDir, '.bangstack', 'manifest.json');
        let currentManifest = null;
        if (fs.existsSync(manifestPath)) {
            currentManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
            if (currentManifest) {
                console.log('Current State:');
                console.log(`  Generated: ${new Date(currentManifest.generated_at).toLocaleString()}`);
                console.log(`  Version: ${currentManifest.workflow_version}`);
                console.log();
            }
        }
        else {
            console.log('Current State: No previous generation found\n');
        }
        // Analyze dependencies
        const analyzer = new dependency_analyzer_1.DependencyAnalyzer();
        const componentAnalysis = [];
        let hasWarnings = false;
        for (const [componentName, component] of Object.entries(workflow.stack || {})) {
            const comp = component;
            // Run dependency analysis
            const analysis = analyzer.analyzeComponent(outputDir, componentName, comp.type, comp.technology);
            const expectedDeps = comp.expected_dependencies?.map((d) => d.service) || [];
            const detectedDeps = analysis.detectedDependencies.map(d => d.service);
            // Compare dependencies
            const warnings = [];
            if (comp.expected_dependencies && comp.expected_dependencies.length > 0) {
                const comparisonWarnings = analyzer.compareDependencies(comp.expected_dependencies, analysis.detectedDependencies);
                warnings.push(...comparisonWarnings);
            }
            // Add analysis errors
            if (analysis.errors && analysis.errors.length > 0) {
                warnings.push(...analysis.errors);
            }
            if (warnings.length > 0) {
                hasWarnings = true;
            }
            componentAnalysis.push({
                name: componentName,
                type: comp.type,
                technology: comp.technology,
                expected: expectedDeps,
                detected: detectedDeps,
                warnings,
            });
        }
        // Compare with current manifest if it exists
        const changes = [];
        if (currentManifest) {
            // Version change
            if (currentManifest.workflow_version !== workflow.workflow.version) {
                changes.push(`📦 Version: ${currentManifest.workflow_version} → ${workflow.workflow.version}`);
            }
            // Infrastructure service changes
            const currentServices = Object.keys(currentManifest.infrastructure_services);
            const newServices = collectInfrastructureServices(workflow);
            const newServiceNames = Object.keys(newServices);
            const removedServices = currentServices.filter(s => !newServiceNames.includes(s));
            const addedServices = newServiceNames.filter(s => !currentServices.includes(s));
            if (removedServices.length > 0 || addedServices.length > 0) {
                changes.push('\nInfrastructure Services:');
                if (removedServices.length > 0) {
                    changes.push(`  ➖ Removed: ${removedServices.join(', ')}`);
                }
                if (addedServices.length > 0) {
                    changes.push(`  ➕ Added: ${addedServices.join(', ')}`);
                }
            }
            if (changes.length > 0) {
                console.log('Changes Detected:');
                changes.forEach(change => console.log(`  ${change}`));
                console.log();
            }
        }
        // Display component analysis
        if (componentAnalysis.length > 0) {
            console.log('Component Dependencies:\n');
            for (const comp of componentAnalysis) {
                const expectedStr = comp.expected.length > 0 ? comp.expected.join(', ') : 'none';
                const detectedStr = comp.detected.length > 0 ? comp.detected.join(', ') : 'none';
                const hasIssues = comp.warnings.length > 0;
                const statusIcon = hasIssues ? '⚠️ ' : '✓';
                console.log(`  ${statusIcon} ${comp.name} (${comp.technology}):`);
                console.log(`     Expected: ${expectedStr}`);
                console.log(`     Detected: ${detectedStr}`);
                if (comp.warnings.length > 0) {
                    comp.warnings.forEach(warning => {
                        console.log(`     ${warning}`);
                    });
                }
                console.log();
            }
        }
        // Recommendations
        if (hasWarnings) {
            console.log('Recommendations:');
            // Check for orphaned client files
            if (currentManifest) {
                for (const [_componentName, component] of Object.entries(currentManifest.components)) {
                    const fileNames = Object.keys(component.implementation_files);
                    const currentServices = collectInfrastructureServices(workflow);
                    const currentServiceNames = Object.keys(currentServices);
                    for (const fileName of fileNames) {
                        const serviceName = fileName.replace('-client.ts', '');
                        if (!currentServiceNames.includes(serviceName)) {
                            console.log(`  • Remove or update ${fileName} (no longer used)`);
                        }
                    }
                }
            }
            // Suggest missing implementations
            for (const comp of componentAnalysis) {
                for (const expected of comp.expected) {
                    if (!comp.detected.includes(expected)) {
                        console.log(`  • Implement ${expected} service integration in ${comp.name} component`);
                    }
                }
            }
            console.log(`  • Run: bang generate ${workflowPath} -o ${outputDir}`);
            console.log();
        }
        // Summary
        const warningCount = componentAnalysis.reduce((sum, comp) => sum + comp.warnings.length, 0);
        if (warningCount > 0) {
            console.log(`Summary: ⚠️  ${warningCount} warning${warningCount === 1 ? '' : 's'} found - manual review required`);
            process.exit(1);
        }
        else {
            console.log('Summary: ✅ No issues found - ready to generate');
            process.exit(0);
        }
    }
    catch (error) {
        console.error(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}\n`);
        process.exit(1);
    }
}
// Helper to collect infrastructure services (same as in ManifestGenerator)
function collectInfrastructureServices(workflow) {
    const services = {};
    for (const [stageName, stage] of Object.entries(workflow.stages || {})) {
        const stageConfig = stage;
        const infraServices = stageConfig.infrastructure?.services || {};
        for (const [serviceName, serviceConfig] of Object.entries(infraServices)) {
            const config = serviceConfig;
            if (!services[serviceName]) {
                services[serviceName] = {
                    providers: [],
                    stages: [],
                };
            }
            if (config.provider && !services[serviceName].providers.includes(config.provider)) {
                services[serviceName].providers.push(config.provider);
            }
            services[serviceName].stages.push(stageName);
        }
    }
    return services;
}
// Attach helper as method for TypeScript context
verifyCommand.collectInfrastructureServices = collectInfrastructureServices;
//# sourceMappingURL=verify.js.map