"use strict";
/**
 * Integration tests for Verify Command
 */
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 });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const child_process_1 = require("child_process");
const yaml = __importStar(require("js-yaml"));
describe('verify command integration', () => {
    let testDir;
    let cliPath;
    beforeEach(() => {
        testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'verify-test-'));
        // Path to the CLI (assuming built in dist/)
        cliPath = path.join(__dirname, '../../../dist/cli/index.js');
    });
    afterEach(() => {
        if (fs.existsSync(testDir)) {
            fs.rmSync(testDir, { recursive: true, force: true });
        }
    });
    /**
     * Helper to create a workflow YAML file
     */
    const createWorkflowFile = (workflow, filename = 'test.workflow.yaml') => {
        const workflowPath = path.join(testDir, filename);
        fs.writeFileSync(workflowPath, yaml.dump(workflow));
        return workflowPath;
    };
    /**
     * Helper to create a component directory with code files
     */
    const createComponentFiles = (componentName, files) => {
        const componentDir = path.join(testDir, componentName, 'src');
        fs.mkdirSync(componentDir, { recursive: true });
        for (const [filename, content] of Object.entries(files)) {
            const filePath = path.join(componentDir, filename);
            const fileDir = path.dirname(filePath);
            // Create intermediate directories
            if (!fs.existsSync(fileDir)) {
                fs.mkdirSync(fileDir, { recursive: true });
            }
            fs.writeFileSync(filePath, content);
        }
    };
    /**
     * Helper to create a manifest
     */
    const createManifest = (manifest) => {
        const manifestDir = path.join(testDir, '.bangstack');
        fs.mkdirSync(manifestDir, { recursive: true });
        fs.writeFileSync(path.join(manifestDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
    };
    /**
     * Helper to run verify command
     */
    const runVerify = (workflowPath, _expectSuccess = true) => {
        try {
            const output = (0, child_process_1.execSync)(`node "${cliPath}" verify "${workflowPath}" -o "${testDir}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
            return { output, exitCode: 0 };
        }
        catch (error) {
            // Command failed (non-zero exit code)
            // Combine stdout and stderr
            const output = [error.stdout, error.stderr].filter(Boolean).join('\n') || error.message;
            return {
                output,
                exitCode: error.status || 1
            };
        }
    };
    describe('basic workflow validation', () => {
        it('should validate a correct workflow', () => {
            const workflow = {
                workflow: {
                    id: 'test-project',
                    version: '1.0.0',
                    name: 'Test Project',
                    description: 'Test Description',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                    },
                },
            };
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode } = runVerify(workflowPath);
            expect(exitCode).toBe(0);
            expect(output).toContain('Test Project');
            expect(output).toContain('1.0.0');
            expect(output).toContain('No issues found');
        });
        it('should reject invalid workflow', () => {
            const workflow = {
                workflow: {
                    // Missing required fields
                    id: 'test',
                },
                stack: {},
            };
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode } = runVerify(workflowPath, false);
            expect(exitCode).toBe(1);
            expect(output.includes('Workflow Validation Failed') || output.includes('Error')).toBe(true);
        });
    });
    describe('dependency analysis', () => {
        it('should detect matching dependencies', () => {
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                        expected_dependencies: [
                            { service: 'redis', usage: 'Caching' },
                        ],
                    },
                },
            };
            // Create component with redis client
            createComponentFiles('api', {
                'index.ts': `
          import { redisClient } from './clients/redis-client';
          export const app = {};
        `,
                'clients/redis-client.ts': 'export const redisClient = {};',
            });
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode } = runVerify(workflowPath);
            expect(exitCode).toBe(0);
            expect(output).toContain('api');
            expect(output).toContain('redis');
            expect(output).toContain('No issues found');
        });
        it('should warn about missing dependencies', () => {
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                        expected_dependencies: [
                            { service: 'redis', usage: 'Caching' },
                            { service: 'queue', usage: 'Jobs' },
                        ],
                    },
                },
            };
            // Create component with only redis client (queue is missing)
            createComponentFiles('api', {
                'index.ts': `
          import { redisClient } from './clients/redis-client';
          export const app = {};
        `,
                'clients/redis-client.ts': 'export const redisClient = {};',
            });
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode } = runVerify(workflowPath, false);
            expect(exitCode).toBe(1);
            expect(output).toContain('warning');
            expect(output).toContain('queue');
        });
        it('should warn about unexpected dependencies', () => {
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                        expected_dependencies: [
                            { service: 'redis', usage: 'Caching' },
                        ],
                    },
                },
            };
            // Create component with redis and unexpected queue client
            createComponentFiles('api', {
                'index.ts': `
          import { redisClient } from './clients/redis-client';
          import { queueClient } from './clients/queue-client';
          export const app = {};
        `,
                'clients/redis-client.ts': 'export const redisClient = {};',
                'clients/queue-client.ts': 'export const queueClient = {};',
            });
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode } = runVerify(workflowPath, false);
            expect(exitCode).toBe(1);
            expect(output).toContain('Unexpected');
            expect(output).toContain('queue');
        });
    });
    describe('manifest comparison', () => {
        it('should detect version changes', () => {
            const oldManifest = {
                workflow_version: '1.0.0',
                generated_at: new Date().toISOString(),
                components: {},
                infrastructure_services: {},
            };
            createManifest(oldManifest);
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '2.0.0', // Changed version
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                    },
                },
            };
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode: _exitCode } = runVerify(workflowPath);
            expect(output).toContain('Version');
            expect(output).toContain('1.0.0');
            expect(output).toContain('2.0.0');
        });
        it('should detect added services', () => {
            const oldManifest = {
                workflow_version: '1.0.0',
                generated_at: new Date().toISOString(),
                components: {},
                infrastructure_services: {
                    redis: { provider: 'local', stages: ['local'] },
                },
            };
            createManifest(oldManifest);
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                    },
                },
                stages: {
                    local: {
                        infrastructure: {
                            databases: { primary: 'postgresql://localhost:5432/test' },
                            services: {
                                redis: { provider: 'local', connection: 'redis://localhost:6379' },
                                queue: { provider: 'local', connection: 'bullmq://localhost:6379' }, // Added
                            },
                        },
                    },
                },
            };
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode: _exitCode } = runVerify(workflowPath);
            expect(output).toContain('Added');
            expect(output).toContain('queue');
        });
        it('should detect removed services', () => {
            const oldManifest = {
                workflow_version: '1.0.0',
                generated_at: new Date().toISOString(),
                components: {},
                infrastructure_services: {
                    redis: { provider: 'local', stages: ['local'] },
                    queue: { provider: 'local', stages: ['local'] },
                },
            };
            createManifest(oldManifest);
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                    },
                },
                stages: {
                    local: {
                        infrastructure: {
                            databases: { primary: 'postgresql://localhost:5432/test' },
                            services: {
                                redis: { provider: 'local', connection: 'redis://localhost:6379' },
                                // queue removed
                            },
                        },
                    },
                },
            };
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode: _exitCode } = runVerify(workflowPath);
            expect(output).toContain('Removed');
            expect(output).toContain('queue');
        });
    });
    describe('recommendations', () => {
        it('should provide recommendations for missing dependencies', () => {
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'typescript/express',
                        expected_dependencies: [
                            { service: 'redis', usage: 'Caching' },
                        ],
                    },
                },
            };
            // Create component without redis client
            createComponentFiles('api', {
                'index.ts': 'export const app = {};',
            });
            const workflowPath = createWorkflowFile(workflow);
            const { output, exitCode } = runVerify(workflowPath, false);
            expect(exitCode).toBe(1);
            expect(output.includes('Recommendations') || output.includes('Implement')).toBe(true);
            expect(output).toContain('redis');
        });
    });
    describe('error handling', () => {
        it('should handle non-existent workflow file', () => {
            const { output, exitCode } = runVerify(path.join(testDir, 'nonexistent.yaml'), false);
            expect(exitCode).toBe(1);
            expect(output.includes('Error') || output.includes('ENOENT')).toBe(true);
        });
        it('should handle invalid YAML', () => {
            const workflowPath = path.join(testDir, 'invalid.yaml');
            fs.writeFileSync(workflowPath, 'invalid: yaml: content: [[[');
            const { output, exitCode } = runVerify(workflowPath, false);
            expect(exitCode).toBe(1);
            expect(output).toContain('Error');
        });
    });
});
//# sourceMappingURL=verify.test.js.map