name: CI Pipeline

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

env:
  GO_VERSION: '1.21'
  CGO_ENABLED: 1

jobs:
  test:
    name: Run Tests
    runs-on: ubuntu-latest
    
    services:
      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Go
      uses: actions/setup-go@v4
      with:
        go-version: ${{ env.GO_VERSION }}

    - name: Cache Go modules
      uses: actions/cache@v3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-

    - name: Install dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y sqlite3 bc curl jq
        go mod download

    - name: Run unit tests
      run: |
        go test -v -race -coverprofile=coverage.out -covermode=atomic ./...

    - name: Run integration tests
      run: |
        go test -v -tags=integration ./test/... -timeout 10m

    - name: Generate coverage report
      run: |
        go tool cover -html=coverage.out -o coverage.html

    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3
      with:
        files: ./coverage.out
        fail_ci_if_error: true

    - name: Build application
      run: |
        go build -o bin/gateway cmd/gateway/main.go
        chmod +x bin/gateway

    - name: Upload build artifacts
      uses: actions/upload-artifact@v3
      with:
        name: gateway-binary-${{ github.sha }}
        path: bin/gateway

  lint:
    name: Lint Code
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Go
      uses: actions/setup-go@v4
      with:
        go-version: ${{ env.GO_VERSION }}

    - name: Run golangci-lint
      uses: golangci/golangci-lint-action@v3
      with:
        version: latest
        args: --timeout=5m

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

    - name: Run Gosec Security Scanner
      uses: securecodewarrior/github-action-gosec@master
      with:
        args: '-fmt sarif -out gosec.sarif ./...'

    - name: Upload SARIF file
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: gosec.sarif

  e2e-tests:
    name: E2E Tests
    runs-on: ubuntu-latest
    needs: [test, lint]
    
    services:
      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Go
      uses: actions/setup-go@v4
      with:
        go-version: ${{ env.GO_VERSION }}

    - name: Setup test environment
      run: |
        sudo apt-get update
        sudo apt-get install -y sqlite3 bc curl jq ffmpeg
        go mod download
        
    - name: Build application
      run: |
        go build -o bin/gateway cmd/gateway/main.go
        chmod +x bin/gateway
        
    - name: Start application
      run: |
        mkdir -p data/{blobs,chunks}
        ./bin/gateway &
        GATEWAY_PID=$!
        echo "GATEWAY_PID=$GATEWAY_PID" >> $GITHUB_ENV
        
    - name: Wait for services
      run: |
        timeout 60 bash -c 'until curl -sf http://localhost:9877/api/health; do sleep 1; done'

    - name: Run E2E tests
      run: |
        if [ -d test/e2e ]; then
          chmod +x test/e2e/*.sh
          ./test/e2e/run_all_tests.sh
        else
          echo "E2E tests directory not found, skipping"
        fi

    - name: Stop application
      if: always()
      run: |
        if [ -n "$GATEWAY_PID" ]; then
          kill $GATEWAY_PID || true
        fi