name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  release:
    types: [ published ]

env:
  CARGO_TERM_COLOR: always
  RUST_VERSION: 1.75.0

jobs:
  test:
    name: Test Suite
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: rustelo_test
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

      redis:
        image: redis:7
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: ${{ env.RUST_VERSION }}
        components: rustfmt, clippy

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

    - name: Install Node dependencies
      run: npm ci

    - name: Cache Cargo dependencies
      uses: actions/cache@v3
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target/
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-

    - name: Install cargo-leptos
      run: cargo install cargo-leptos --version 0.2.20

    - name: Check formatting
      run: cargo fmt --all -- --check

    - name: Run Clippy
      run: cargo clippy --all-targets --features "auth,content-db,crypto,email,metrics,examples" -- -D warnings

    - name: Run tests
      run: cargo test --features "auth,content-db,crypto,email,metrics,examples"
      env:
        DATABASE_URL: postgresql://postgres:postgres@localhost:5432/rustelo_test
        REDIS_URL: redis://localhost:6379

    - name: Build frontend
      run: npm run build

    - name: Build application
      run: cargo leptos build --release --features production --no-default-features

  security:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: ${{ env.RUST_VERSION }}

    - name: Install cargo-audit
      run: cargo install cargo-audit

    - name: Run security audit
      run: cargo audit

    - name: Run cargo-deny
      uses: EmbarkStudios/cargo-deny-action@v1

  build:
    name: Build Docker Image
    runs-on: ubuntu-latest
    needs: [test, security]
    if: github.event_name == 'push' || github.event_name == 'release'

    steps:
    - uses: actions/checkout@v4

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    - name: Login to Docker Hub
      if: github.event_name == 'release'
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: |
          ${{ secrets.DOCKER_USERNAME }}/rustelo
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=sha,prefix={{branch}}-

    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        platforms: linux/amd64,linux/arm64
        push: ${{ github.event_name == 'release' }}
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/develop'
    environment: staging

    steps:
    - uses: actions/checkout@v4

    - name: Deploy to staging
      run: |
        echo "Deploying to staging environment..."
        # Add your staging deployment commands here
        # Example: kubectl apply -f k8s/staging/
        # Example: docker-compose -f docker-compose.staging.yml up -d

    - name: Run health check
      run: |
        echo "Running health check..."
        # Add health check commands here
        # Example: curl -f https://staging.yourapp.com/health

  deploy-production:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: build
    if: github.event_name == 'release'
    environment: production

    steps:
    - uses: actions/checkout@v4

    - name: Deploy to production
      run: |
        echo "Deploying to production environment..."
        # Add your production deployment commands here
        # Example: kubectl apply -f k8s/production/
        # Example: docker-compose -f docker-compose.prod.yml up -d

    - name: Run health check
      run: |
        echo "Running health check..."
        # Add health check commands here
        # Example: curl -f https://yourapp.com/health

    - name: Notify deployment
      if: always()
      run: |
        echo "Notifying deployment status..."
        # Add notification commands here
        # Example: Send Slack notification, email, etc.

  benchmark:
    name: Performance Benchmarks
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'

    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: ${{ env.RUST_VERSION }}

    - name: Run benchmarks
      run: cargo bench --features production --no-default-features

    - name: Store benchmark results
      uses: benchmark-action/github-action-benchmark@v1
      with:
        tool: 'cargo'
        output-file-path: target/criterion/report/index.html
        github-token: ${{ secrets.GITHUB_TOKEN }}
        auto-push: true
        comment-on-alert: true
        alert-threshold: '200%'
        fail-on-alert: true

  cleanup:
    name: Cleanup
    runs-on: ubuntu-latest
    if: always()
    needs: [test, security, build, deploy-staging, deploy-production]

    steps:
    - name: Cleanup artifacts
      run: |
        echo "Cleaning up temporary artifacts..."
        # Add cleanup commands here if needed
