import { describe, it, expect } from '@jest/globals';
import { GitHubActionsGenerator } from './github-actions-generator';
import { GeneratorContext } from '../types';

describe('GitHubActionsGenerator', () => {
  const generator = new GitHubActionsGenerator();

  const mockWorkflow = {
    workflow: {
      id: 'test-workflow',
      name: 'Test Workflow',
    },
    stack: {
      'web-app': {
        type: 'frontend',
        technology: 'react',
      },
      'api': {
        type: 'backend',
        technology: 'typescript/express',
      },
      'database': {
        type: 'database',
        technology: 'postgresql',
      },
    },
    testing: {
      unit_tests: [
        { component: 'web-app.login-form', scenarios: ['test1'] },
        { component: 'api.login-endpoint', scenarios: ['test2'] },
      ],
      integration_tests: [
        { name: 'complete-flow', steps: [] },
      ],
      e2e_tests: [
        { name: 'user-can-login', steps: [] },
      ],
    },
    deployment: {
      'web-app': {
        build_command: 'npm run build',
        output_directory: 'dist',
      },
      'api': {
        build_command: 'npm run build',
        start_command: 'npm start',
      },
    },
  };

  const mockContext: GeneratorContext = {
    workflow: mockWorkflow as any,
    executionPlan: {} as any,
    outputDirectory: '/test/output',
  };

  it('should have correct metadata', () => {
    expect(generator.id).toBe('github-actions-cicd');
    expect(generator.name).toBe('GitHub Actions CI/CD Generator');
    expect(generator.description).toBe('Generates GitHub Actions workflows for CI/CD');
  });

  it('should generate test workflow', () => {
    const result = generator.generate(mockContext);

    expect(result.files.length).toBeGreaterThan(0);

    const testWorkflow = result.files.find(f => f.path.includes('test.yml'));
    expect(testWorkflow).toBeDefined();
    expect(testWorkflow?.content).toContain('name: Test');
    expect(testWorkflow?.content).toContain('test-frontend');
    expect(testWorkflow?.content).toContain('test-backend');
    expect(testWorkflow?.content).toContain('test-e2e');
  });

  it('should generate build workflow', () => {
    const result = generator.generate(mockContext);

    const buildWorkflow = result.files.find(f => f.path.includes('build.yml'));
    expect(buildWorkflow).toBeDefined();
    expect(buildWorkflow?.content).toContain('name: Build');
    expect(buildWorkflow?.content).toContain('build-frontend');
    expect(buildWorkflow?.content).toContain('build-backend');
  });

  it('should generate deploy workflow', () => {
    const result = generator.generate(mockContext);

    const deployWorkflow = result.files.find(f => f.path.includes('deploy.yml'));
    expect(deployWorkflow).toBeDefined();
    expect(deployWorkflow?.content).toContain('name: Deploy');
  });

  it('should include database services in workflows', () => {
    const result = generator.generate(mockContext);

    const testWorkflow = result.files.find(f => f.path.includes('test.yml'));
    expect(testWorkflow?.content).toContain('postgres:');
    expect(testWorkflow?.content).toContain('image: postgres:15-alpine');
  });

  it('should not generate workflows when testing is not configured', () => {
    const contextWithoutTesting: GeneratorContext = {
      ...mockContext,
      workflow: {
        ...mockWorkflow,
        testing: undefined,
      } as any,
    };

    const result = generator.generate(contextWithoutTesting);

    const testWorkflow = result.files.find(f => f.path.includes('test.yml'));
    expect(testWorkflow).toBeUndefined();
  });
});
