"use strict";
/**
 * GitHub Actions CI/CD Generator
 * Generates GitHub Actions workflows for testing, building, and deploying
 */
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.GitHubActionsGenerator = void 0;
const path = __importStar(require("path"));
class GitHubActionsGenerator {
    id = 'github-actions-cicd';
    name = 'GitHub Actions CI/CD Generator';
    description = 'Generates GitHub Actions workflows for CI/CD';
    generate(context) {
        const { workflow, outputDirectory } = context;
        const files = [];
        // Generate test workflow
        if (workflow.testing) {
            files.push(this.generateTestWorkflow(workflow, outputDirectory));
        }
        // Generate build workflow
        if (workflow.deployment) {
            files.push(this.generateBuildWorkflow(workflow, outputDirectory));
        }
        // Generate deploy workflow (if deployment config exists)
        if (workflow.deployment && this.hasDeploymentConfig(workflow)) {
            files.push(this.generateDeployWorkflow(workflow, outputDirectory));
        }
        return { files };
    }
    generateTestWorkflow(workflow, outputDir) {
        const hasUnitTests = workflow.testing?.unit_tests?.length > 0;
        const hasIntegrationTests = workflow.testing?.integration_tests?.length > 0;
        const hasE2ETests = workflow.testing?.e2e_tests?.length > 0;
        // Find stack components
        const frontendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'frontend');
        const backendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'backend');
        const databaseComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'database');
        let content = `name: Test

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
`;
        // Frontend tests job
        if (frontendComponent && hasUnitTests) {
            const [componentName] = frontendComponent;
            content += `  test-frontend:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: ${componentName}/package-lock.json

      - name: Install dependencies
        working-directory: ./${componentName}
        run: npm ci

      - name: Run lint
        working-directory: ./${componentName}
        run: npm run lint

      - name: Run unit tests
        working-directory: ./${componentName}
        run: npm test -- --run

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./${componentName}/coverage/coverage-final.json
          flags: frontend

`;
        }
        // Backend tests job
        if (backendComponent && (hasUnitTests || hasIntegrationTests)) {
            const [componentName] = backendComponent;
            const dbTech = databaseComponent ? databaseComponent[1].technology : null;
            content += `  test-backend:
    runs-on: ubuntu-latest

`;
            // Add database service if needed
            if (dbTech === 'postgresql' && hasIntegrationTests) {
                content += `    services:
      postgres:
        image: postgres:15-alpine
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: test_db
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

`;
            }
            content += `    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: ${componentName}/package-lock.json

      - name: Install dependencies
        working-directory: ./${componentName}
        run: npm ci

      - name: Run tests
        working-directory: ./${componentName}
        run: npm test
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/test_db
          JWT_SECRET: test-secret-key
          NODE_ENV: test

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./${componentName}/coverage/coverage-final.json
          flags: backend

`;
        }
        // E2E tests job
        if (frontendComponent && backendComponent && hasE2ETests) {
            const [frontendName] = frontendComponent;
            const [backendName] = backendComponent;
            const dbTech = databaseComponent ? databaseComponent[1].technology : null;
            content += `  test-e2e:
    runs-on: ubuntu-latest

`;
            // Add database service for e2e tests
            if (dbTech === 'postgresql') {
                content += `    services:
      postgres:
        image: postgres:15-alpine
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: test_db
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

`;
            }
            content += `    steps:
      - uses: actions/checkout@v4

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

      - name: Install frontend dependencies
        working-directory: ./${frontendName}
        run: npm ci

      - name: Install backend dependencies
        working-directory: ./${backendName}
        run: npm ci

      - name: Install Playwright browsers
        working-directory: ./${frontendName}
        run: npx playwright install --with-deps chromium

      - name: Build frontend
        working-directory: ./${frontendName}
        run: npm run build

      - name: Build backend
        working-directory: ./${backendName}
        run: npm run build

      - name: Run E2E tests
        working-directory: ./${frontendName}
        run: npm run e2e
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/test_db
          JWT_SECRET: test-secret-key
          NODE_ENV: test

      - name: Upload Playwright report
        uses: actions/upload-artifact@v3
        if: always()
        with:
          name: playwright-report
          path: ${frontendName}/playwright-report/
          retention-days: 30
`;
        }
        return {
            path: path.join(outputDir, '.github', 'workflows', 'test.yml'),
            content,
            overwrite: true,
        };
    }
    generateBuildWorkflow(workflow, outputDir) {
        const frontendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'frontend');
        const backendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'backend');
        let content = `name: Build

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
`;
        // Frontend build job
        if (frontendComponent) {
            const [componentName, _component] = frontendComponent;
            const deployment = workflow.deployment?.[componentName];
            content += `  build-frontend:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: ${componentName}/package-lock.json

      - name: Install dependencies
        working-directory: ./${componentName}
        run: npm ci

      - name: Build
        working-directory: ./${componentName}
        run: ${deployment?.build_command || 'npm run build'}
`;
            if (deployment?.output_directory) {
                content += `
      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: frontend-build
          path: ${componentName}/${deployment.output_directory}
          retention-days: 7
`;
            }
            content += `
`;
        }
        // Backend build job
        if (backendComponent) {
            const [componentName, _component] = backendComponent;
            const deployment = workflow.deployment?.[componentName];
            content += `  build-backend:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: ${componentName}/package-lock.json

      - name: Install dependencies
        working-directory: ./${componentName}
        run: npm ci

      - name: Build
        working-directory: ./${componentName}
        run: ${deployment?.build_command || 'npm run build'}

      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: backend-build
          path: ${componentName}/dist
          retention-days: 7
`;
        }
        return {
            path: path.join(outputDir, '.github', 'workflows', 'build.yml'),
            content,
            overwrite: true,
        };
    }
    generateDeployWorkflow(workflow, outputDir) {
        const _frontendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'frontend');
        const _backendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'backend');
        const content = `name: Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    needs: [build-frontend, build-backend]
    if: github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v4

      - name: Download frontend artifacts
        uses: actions/download-artifact@v3
        with:
          name: frontend-build
          path: ./build/frontend

      - name: Download backend artifacts
        uses: actions/download-artifact@v3
        with:
          name: backend-build
          path: ./build/backend

      # Add deployment steps based on your hosting provider
      # Examples: Vercel, AWS, Heroku, etc.

      - name: Deploy notification
        run: echo "Deployment artifacts ready for manual deployment"
`;
        return {
            path: path.join(outputDir, '.github', 'workflows', 'deploy.yml'),
            content,
            overwrite: true,
        };
    }
    hasDeploymentConfig(workflow) {
        return workflow.deployment && Object.keys(workflow.deployment).length > 0;
    }
}
exports.GitHubActionsGenerator = GitHubActionsGenerator;
//# sourceMappingURL=github-actions-generator.js.map