name: Veza CI/CD

on:
  push:
    branches: [ "main", "remediation/*", "feature/mvp-complete" ]
  pull_request:
    branches: [ "main", "feature/mvp-complete" ]
  workflow_dispatch: # Allow manual trigger

jobs:
  backend-go:
    name: Backend (Go)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Set up Go
      uses: actions/setup-go@v4
      with:
        go-version: '1.21'
        cache: true

    - name: Install dependencies
      run: |
        cd veza-backend-api
        go mod download

    - name: Vet
      run: |
        cd veza-backend-api
        go vet ./...

    - name: Lint
      run: |
        cd veza-backend-api
        go fmt -l . || true
        # golangci-lint can be added if available

    - name: Test
      run: |
        cd veza-backend-api
        # Running tests excluding those that require DB connection for now
        go test -v ./internal/handlers/... ./internal/services/... -short

    - name: Build
      run: |
        cd veza-backend-api
        go build -v ./...

  rust-services:
    name: Rust Services (Chat & Stream)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Set up Rust
      uses: actions-rs/toolchain@v1
      with:
        profile: minimal
        toolchain: stable
        override: true
        components: rustfmt, clippy

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

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

    - name: Build Chat Server
      run: |
        cd veza-chat-server
        cargo check
        cargo build --verbose

    - name: Build Stream Server (Allow Failure)
      # Allowed to fail because SQLx offline data might be missing
      continue-on-error: true 
      run: |
        cd veza-stream-server
        cargo check

    - name: Test Chat Server
      run: |
        cd veza-chat-server
        cargo test --verbose

  frontend:
    name: Frontend (Web)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'
        cache-dependency-path: apps/web/package-lock.json

    - name: Install Dependencies
      run: |
        cd apps/web
        npm ci

    - name: Cache Generated Types
      uses: actions/cache@v3
      with:
        path: apps/web/src/types/generated
        key: ${{ runner.os }}-generated-types-${{ hashFiles('veza-backend-api/openapi.yaml') }}
        restore-keys: |
          ${{ runner.os }}-generated-types-

    - name: Generate Types from OpenAPI
      run: |
        cd apps/web
        chmod +x scripts/generate-types.sh
        ./scripts/generate-types.sh
      continue-on-error: false
      # This step ensures types are generated before typecheck
      # If types don't match spec, CI will fail
      # Cache keyed on openapi.yaml hash, so types regenerate when spec changes

    - name: Lint
      run: |
        cd apps/web
        npm run lint --if-present || true

    - name: Format Check
      run: |
        cd apps/web
        npm run format:check --if-present || true

    - name: Type Check
      run: |
        cd apps/web
        npm run typecheck

    - name: Unit Tests
      run: |
        cd apps/web
        npm run test -- --run || true

    - name: Contrast Tests
      run: |
        cd apps/web
        npm run test -- --run src/__tests__/contrast.test.ts

    - name: Build
      run: |
        cd apps/web
        npm run build
