"use strict";
/**
 * Enhanced Testing Generator
 * Generates comprehensive test configurations based on the new enhanced testing schema
 * Handles: test frameworks, coverage, database testing, worker testing, CI/CD integration
 */
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.EnhancedTestingGenerator = void 0;
const path = __importStar(require("path"));
class EnhancedTestingGenerator {
    id = 'enhanced-testing';
    name = 'Enhanced Testing Generator';
    description = 'Generates comprehensive test configurations from enhanced testing schema';
    testFramework = 'vitest'; // Default, but configurable
    generate(context) {
        const { workflow, outputDirectory } = context;
        const files = [];
        if (!workflow.testing) {
            return { files: [] };
        }
        const testing = workflow.testing;
        // Skip if using legacy format (handled by other generators)
        if (testing.unit_tests || testing.integration_tests || testing.e2e_tests) {
            return { files: [] };
        }
        // Only proceed if new frameworks-based config is present
        if (!testing.frameworks) {
            return { files: [] };
        }
        // Generate backend test configurations
        const backendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'backend');
        if (backendComponent) {
            files.push(...this.generateBackendTestConfig(backendComponent[0], testing, outputDirectory));
        }
        // Generate frontend test configurations
        const frontendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'frontend');
        if (frontendComponent) {
            files.push(...this.generateFrontendTestConfig(frontendComponent[0], testing, outputDirectory));
        }
        // Generate CI/CD configuration if specified
        if (testing.ci_cd) {
            files.push(...this.generateCICDConfig(testing, outputDirectory));
        }
        // Generate test fixtures loader if specified
        if (testing.fixtures) {
            files.push(this.generateFixturesLoader(testing, outputDirectory));
        }
        // Generate test factories if specified
        if (testing.factories) {
            files.push(...this.generateFactories(testing, outputDirectory));
        }
        return { files };
    }
    /**
     * Generate backend test configuration
     */
    generateBackendTestConfig(componentName, testing, outputDir) {
        const files = [];
        const unitConfig = testing.frameworks?.unit;
        const integrationConfig = testing.frameworks?.integration;
        // Generate Vitest or Jest config for backend
        if (unitConfig || integrationConfig) {
            const framework = unitConfig?.framework || integrationConfig?.framework || 'vitest';
            if (framework === 'vitest') {
                files.push(this.generateVitestConfig(componentName, testing, outputDir));
            }
            else if (framework === 'jest') {
                files.push(this.generateJestConfig(componentName, testing, outputDir));
            }
            // Generate test setup file
            files.push(this.generateTestSetup(componentName, testing, outputDir));
            // Generate database test helpers if database testing is configured
            if (testing.database) {
                files.push(this.generateDatabaseTestHelpers(componentName, testing, outputDir));
            }
            // Generate API mock helpers if external API mocking is configured
            if (testing.external_apis) {
                files.push(this.generateAPIMockHelpers(componentName, testing, outputDir));
            }
            // Generate worker test helpers if worker testing is configured
            if (testing.workers) {
                files.push(this.generateWorkerTestHelpers(componentName, testing, outputDir));
            }
        }
        return files;
    }
    /**
     * Generate frontend test configuration
     */
    generateFrontendTestConfig(componentName, testing, outputDir) {
        const files = [];
        const e2eConfig = testing.frameworks?.e2e;
        const componentConfig = testing.frameworks?.component;
        // Generate Playwright config for E2E tests
        if (e2eConfig?.framework === 'playwright') {
            files.push(this.generatePlaywrightConfig(componentName, testing, outputDir));
        }
        // Generate Cypress config for E2E tests
        if (e2eConfig?.framework === 'cypress') {
            files.push(this.generateCypressConfig(componentName, testing, outputDir));
        }
        // Generate component test config (Vitest + Testing Library)
        if (componentConfig) {
            files.push(this.generateComponentTestConfig(componentName, testing, outputDir));
        }
        return files;
    }
    /**
     * Generate Vitest configuration
     */
    generateVitestConfig(componentName, testing, outputDir) {
        const coverage = testing.coverage;
        const customConfig = testing.frameworks?.unit?.config || {};
        const content = `import { defineConfig } from 'vitest/config';
import path from 'path';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
    setupFiles: ['./src/test/setup.ts'],
    ${coverage?.threshold ? `coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html', 'lcov'],
      ${coverage.threshold.global ? `thresholds: {
        statements: ${coverage.threshold.global.statements || 80},
        branches: ${coverage.threshold.global.branches || 80},
        functions: ${coverage.threshold.global.functions || 80},
        lines: ${coverage.threshold.global.lines || 80},
      },` : ''}
      ${coverage.exclude ? `exclude: ${JSON.stringify(coverage.exclude, null, 6)},` : ''}
    },` : ''}
    ${Object.keys(customConfig).length > 0 ? `// Custom configuration
    ${Object.entries(customConfig).map(([key, value]) => `${key}: ${JSON.stringify(value)},`).join('\n    ')}` : ''}
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
});
`;
        return {
            path: path.join(outputDir, componentName, 'vitest.config.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate Jest configuration
     */
    generateJestConfig(componentName, testing, outputDir) {
        const coverage = testing.coverage;
        const content = `module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  roots: ['<rootDir>/src'],
  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
  transform: {
    '^.+\\\\.ts$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/src/test/setup.ts'],
  ${coverage?.threshold ? `coverageThreshold: {
    global: {
      statements: ${coverage.threshold.global?.statements || 80},
      branches: ${coverage.threshold.global?.branches || 80},
      functions: ${coverage.threshold.global?.functions || 80},
      lines: ${coverage.threshold.global?.lines || 80},
    },
  },` : ''}
  coverageDirectory: 'coverage',
  collectCoverageFrom: [
    'src/**/*.ts',
    '!src/**/*.test.ts',
    '!src/**/*.spec.ts',
    '!src/test/**',
    ${coverage?.exclude ? coverage.exclude.map(e => `'!${e}',`).join('\n    ') : ''}
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
};
`;
        return {
            path: path.join(outputDir, componentName, 'jest.config.js'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate test setup file
     */
    generateTestSetup(componentName, testing, outputDir) {
        const hasDatabase = !!testing.database;
        const hasWorkers = !!testing.workers;
        const hasExternalAPIs = !!testing.external_apis;
        const content = `/**
 * Test setup and configuration
 * Auto-generated from enhanced testing configuration
 */

// Mock environment variables
process.env.NODE_ENV = 'test';
${hasDatabase ? `process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test';` : ''}
process.env.JWT_SECRET = 'test-secret-key';

${hasDatabase ? `// Database test utilities
import { setupTestDatabase, teardownTestDatabase } from './helpers/database';

beforeAll(async () => {
  await setupTestDatabase();
});

afterAll(async () => {
  await teardownTestDatabase();
});

afterEach(async () => {
  // Clean up test data after each test
  ${testing.database?.reset_strategy === 'truncate' ? `await truncateAllTables();` : `await dropAndRecreateTables();`}
});
` : ''}

${hasWorkers ? `// Worker test utilities
import { setupTestQueue, teardownTestQueue } from './helpers/workers';

beforeAll(async () => {
  await setupTestQueue();
});

afterAll(async () => {
  await teardownTestQueue();
});
` : ''}

${hasExternalAPIs ? `// API mocking setup
import { setupAPIMocks } from './helpers/api-mocks';

beforeAll(() => {
  setupAPIMocks();
});
` : ''}

// Global test utilities
export const createTestUser = async () => {
  return {
    id: '123e4567-e89b-12d3-a456-426614174000',
    email: 'test@example.com',
    name: 'Test User',
  };
};

export const generateTestToken = (userId: string) => {
  // TODO: Implement test JWT generation based on your auth setup
  return 'test-jwt-token';
};
`;
        return {
            path: path.join(outputDir, componentName, 'src', 'test', 'setup.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate database test helpers
     */
    generateDatabaseTestHelpers(componentName, testing, outputDir) {
        const strategy = testing.database?.strategy || 'mock';
        let setupCode = '';
        let teardownCode = '';
        switch (strategy) {
            case 'testcontainers':
                setupCode = `  // Start PostgreSQL container
  const container = await new PostgreSqlContainer()
    .withDatabase('test')
    .withUsername('test')
    .withPassword('test')
    .start();

  process.env.DATABASE_URL = container.getConnectionUri();

  // Run migrations
  await runMigrations();`;
                teardownCode = `  await container.stop();`;
                break;
            case 'sqlite':
                setupCode = `  // Use in-memory SQLite for tests
  process.env.DATABASE_URL = 'sqlite::memory:';
  await runMigrations();`;
                teardownCode = `  // SQLite in-memory DB is automatically cleaned up`;
                break;
            case 'dedicated':
                setupCode = `  // Connect to dedicated test database
  await runMigrations();`;
                teardownCode = `  await dropAllTables();`;
                break;
            case 'mock':
            default:
                setupCode = `  // Mock database calls
  jest.mock('../database', () => ({
    db: mockDatabase,
  }));`;
                teardownCode = `  // No teardown needed for mocks`;
        }
        const content = `/**
 * Database test helpers
 * Strategy: ${strategy}
 */

${strategy === 'testcontainers' ? `import { PostgreSqlContainer } from 'testcontainers';` : ''}

let container: any;

export async function setupTestDatabase() {
${setupCode}
}

export async function teardownTestDatabase() {
${teardownCode}
}

export async function truncateAllTables() {
  // TODO: Implement table truncation
  // This should truncate all tables while preserving schema
}

export async function dropAndRecreateTables() {
  // TODO: Implement drop and recreate
  // This should drop all tables and re-run migrations
}

async function runMigrations() {
  // TODO: Run your migrations here
  // Example: await prisma.$executeRawUnsafe('CREATE TABLE IF NOT EXISTS users...')
}

${strategy === 'dedicated' ? `async function dropAllTables() {
  // TODO: Drop all tables
}` : ''}
`;
        return {
            path: path.join(outputDir, componentName, 'src', 'test', 'helpers', 'database.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate API mock helpers
     */
    generateAPIMockHelpers(componentName, testing, outputDir) {
        const strategy = testing.external_apis?.strategy || 'msw';
        const mocks = testing.external_apis?.mock_definitions || [];
        const content = `/**
 * External API mocking helpers
 * Strategy: ${strategy}
 */

${strategy === 'msw' ? `import { setupServer } from 'msw/node';
import { http, HttpResponse } from 'msw';

const handlers = [
${mocks.map(mock => `  // Mock for ${mock.service}
  http.get('${mock.base_url}/*', () => {
    return HttpResponse.json({ mocked: true });
  }),`).join('\n')}
];

export const server = setupServer(...handlers);

export function setupAPIMocks() {
  server.listen({ onUnhandledRequest: 'warn' });
}

afterEach(() => server.resetHandlers());
afterAll(() => server.close());
` : strategy === 'nock' ? `import nock from 'nock';

export function setupAPIMocks() {
${mocks.map(mock => `  nock('${mock.base_url}')
    .get(() => true)
    .reply(200, { mocked: true });`).join('\n\n')}
}

export function cleanupAPIMocks() {
  nock.cleanAll();
}
` : `// Custom API mocking setup
export function setupAPIMocks() {
  // TODO: Implement custom API mocking
}
`}
`;
        return {
            path: path.join(outputDir, componentName, 'src', 'test', 'helpers', 'api-mocks.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate worker test helpers
     */
    generateWorkerTestHelpers(componentName, testing, outputDir) {
        const strategy = testing.workers?.strategy || 'mock_queue';
        const autoProcess = testing.workers?.auto_process ?? true;
        const content = `/**
 * Worker/queue test helpers
 * Strategy: ${strategy}
 */

${strategy === 'test_redis' ? `import Redis from 'ioredis-mock';
import { Queue } from 'bullmq';

let testRedis: Redis;
let testQueue: Queue;

export async function setupTestQueue() {
  testRedis = new Redis();
  testQueue = new Queue('test-queue', { connection: testRedis });
}

export async function teardownTestQueue() {
  await testQueue.close();
  await testRedis.quit();
}

export function getTestQueue() {
  return testQueue;
}

${autoProcess ? `export async function processJobs() {
  // Auto-process jobs for testing
  await testQueue.drain();
}` : ''}
` : strategy === 'in_memory' ? `type Job = {
  id: string;
  data: any;
  name: string;
};

const jobs: Job[] = [];

export async function setupTestQueue() {
  jobs.length = 0;
}

export async function teardownTestQueue() {
  jobs.length = 0;
}

export function addJob(name: string, data: any) {
  jobs.push({ id: Math.random().toString(), name, data });
}

export function getJobs() {
  return [...jobs];
}

export async function processJobs() {
  // Process all queued jobs
  const toProcess = [...jobs];
  jobs.length = 0;
  return toProcess;
}
` : `// Mock queue implementation
export async function setupTestQueue() {
  // TODO: Setup mock queue
}

export async function teardownTestQueue() {
  // TODO: Cleanup mock queue
}
`}
`;
        return {
            path: path.join(outputDir, componentName, 'src', 'test', 'helpers', 'workers.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate Playwright configuration
     */
    generatePlaywrightConfig(componentName, testing, outputDir) {
        const e2eConfig = testing.frameworks?.e2e;
        const browsers = e2eConfig?.browsers || ['chromium'];
        const content = `import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  use: {
    baseURL: 'http://localhost:5173',
    trace: 'on-first-retry',
  },

  projects: [
${browsers.map(browser => `    {
      name: '${browser}',
      use: { ...devices['${browser === 'chromium' ? 'Desktop Chrome' : browser === 'firefox' ? 'Desktop Firefox' : 'Desktop Safari'}'] },
    },`).join('\n')}
  ],

  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:5173',
    reuseExistingServer: !process.env.CI,
  },
});
`;
        return {
            path: path.join(outputDir, componentName, 'playwright.config.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate Cypress configuration
     */
    generateCypressConfig(componentName, testing, outputDir) {
        const content = `import { defineConfig } from 'cypress';

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:5173',
    setupNodeEvents(on, config) {
      // implement node event listeners here
    },
  },
  component: {
    devServer: {
      framework: 'react',
      bundler: 'vite',
    },
  },
});
`;
        return {
            path: path.join(outputDir, componentName, 'cypress.config.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate component test configuration
     */
    generateComponentTestConfig(componentName, testing, outputDir) {
        const content = `import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/test/component-setup.ts'],
  },
});
`;
        return {
            path: path.join(outputDir, componentName, 'vitest.config.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate CI/CD configuration
     */
    generateCICDConfig(testing, outputDir) {
        const files = [];
        const provider = testing.ci_cd?.provider;
        if (provider === 'github_actions') {
            files.push(this.generateGitHubActionsConfig(testing, outputDir));
        }
        else if (provider === 'gitlab_ci') {
            files.push(this.generateGitLabCIConfig(testing, outputDir));
        }
        return files;
    }
    /**
     * Generate GitHub Actions workflow
     */
    generateGitHubActionsConfig(testing, outputDir) {
        const testOnPR = testing.ci_cd?.test_on_pr ?? true;
        const requirePassing = testing.ci_cd?.test_requirements?.require_passing ?? true;
        const minCoverage = testing.ci_cd?.test_requirements?.minimum_coverage || 80;
        const content = `name: Test

on:
${testOnPR ? `  pull_request:
    branches: [ main, develop ]
` : ''}  push:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test -- --coverage

      - name: Check coverage
        run: |
          COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
          if (( $(echo "$COVERAGE < ${minCoverage}" | bc -l) )); then
            echo "Coverage $COVERAGE% is below minimum ${minCoverage}%"
            exit 1
          fi

      - name: Upload coverage reports
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
          flags: unittests
          name: codecov-umbrella
          ${requirePassing ? `fail_ci_if_error: true` : ''}
`;
        return {
            path: path.join(outputDir, '.github', 'workflows', 'test.yml'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate GitLab CI configuration
     */
    generateGitLabCIConfig(testing, outputDir) {
        const minCoverage = testing.ci_cd?.test_requirements?.minimum_coverage || 80;
        const content = `image: node:18

stages:
  - test

test:
  stage: test
  script:
    - npm ci
    - npm test -- --coverage
  coverage: '/Lines\\s*:\\s*(\\d+\\.\\d+)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "main"'
  coverage_threshold: ${minCoverage}
`;
        return {
            path: path.join(outputDir, '.gitlab-ci.yml'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate fixtures loader
     */
    generateFixturesLoader(testing, outputDir) {
        const fixturesPath = testing.fixtures?.path || './test/fixtures';
        const content = `/**
 * Test fixtures loader
 */

import * as fs from 'fs';
import * as path from 'path';

const FIXTURES_DIR = path.join(__dirname, '${fixturesPath}');

export function loadFixture<T = any>(name: string): T {
  const fixturePath = path.join(FIXTURES_DIR, \`\${name}.json\`);
  const content = fs.readFileSync(fixturePath, 'utf-8');
  return JSON.parse(content);
}

export function loadAllFixtures(): Record<string, any> {
  const fixtures: Record<string, any> = {};
  const files = fs.readdirSync(FIXTURES_DIR);

  for (const file of files) {
    if (file.endsWith('.json')) {
      const name = file.replace('.json', '');
      fixtures[name] = loadFixture(name);
    }
  }

  return fixtures;
}
`;
        return {
            path: path.join(outputDir, 'src', 'test', 'helpers', 'fixtures.ts'),
            content,
            overwrite: true,
        };
    }
    /**
     * Generate test factories
     */
    generateFactories(testing, outputDir) {
        const files = [];
        const library = testing.factories?.library || 'fishery';
        if (library === 'fishery') {
            files.push(this.generateFisheryFactory(outputDir));
        }
        return files;
    }
    /**
     * Generate Fishery factory
     */
    generateFisheryFactory(outputDir) {
        const content = `/**
 * Test data factories using Fishery
 */

import { Factory } from 'fishery';

interface User {
  id: string;
  email: string;
  name: string;
  createdAt: Date;
}

export const userFactory = Factory.define<User>(({ sequence }) => ({
  id: \`user-\${sequence}\`,
  email: \`user\${sequence}@example.com\`,
  name: \`Test User \${sequence}\`,
  createdAt: new Date(),
}));

// Add more factories as needed
`;
        return {
            path: path.join(outputDir, 'src', 'test', 'factories', 'index.ts'),
            content,
            overwrite: true,
        };
    }
}
exports.EnhancedTestingGenerator = EnhancedTestingGenerator;
//# sourceMappingURL=enhanced-testing-generator.js.map