name: Deploy to Staging

on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths-ignore:
      - 'docs/**'
      - 'README.md'
      - 'CHANGELOG.md'
      - '.forgejo/ISSUE_TEMPLATE/**'
      - '**/*.md'

concurrency:
  group: deploy-staging-${{ gitea.workflow }}-${{ gitea.ref }}
  cancel-in-progress: false

permissions:
  contents: read
  actions: read

env:
  DEPLOY_ENV: staging
  COMPOSE_FILE: deployments/docker-compose.staging.yml

jobs:
  pre-deployment-gates:
    name: Pre-Deployment Gates
    runs-on: self-hosted
    timeout-minutes: 10

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

    - name: Verify HIPAA config signature (HIPAA mode only)
      run: |
        echo "=== Verifying HIPAA config signature ==="
        
        # Check if we're deploying in HIPAA mode
        if [ -f "deployments/configs/worker/docker-staging.yaml" ]; then
          if grep -q "compliance_mode.*hipaa" deployments/configs/worker/docker-staging.yaml; then
            echo "HIPAA mode detected - checking signature..."
            
            # Check if signature file exists
            if [ -f "deployments/configs/worker/docker-hipaa.yaml.sig" ]; then
              echo "✓ HIPAA config signature file exists"
              
              # In production, use cosign to verify:
              # cosign verify-blob \
              #   --key ${{ secrets.COSIGN_PUBLIC_KEY }} \
              #   --signature deployments/configs/worker/docker-hipaa.yaml.sig \
              #   deployments/configs/worker/docker-hipaa.yaml
              
              # For now, just check it's not the placeholder
              if grep -q "UNSIGNED_PLACEHOLDER" deployments/configs/worker/docker-hipaa.yaml.sig; then
                echo "⚠ WARNING: HIPAA config is using placeholder signature"
                echo "Deployment proceeding but this should be fixed for production"
              else
                echo "✓ HIPAA config appears to be signed"
              fi
            else
              echo "✗ HIPAA config signature file NOT FOUND"
              echo "This is a WARNING - deployment will proceed but may be blocked in production"
            fi
          else
            echo "Not in HIPAA mode - skipping signature verification"
          fi
        fi

    - name: Check audit sink reachability
      run: |
        echo "=== Checking audit sink reachability ==="
        
        # Check if audit sink check script exists
        if [ -f "scripts/check-audit-sink.sh" ]; then
          chmod +x scripts/check-audit-sink.sh
          ./scripts/check-audit-sink.sh --env staging --timeout 10s || {
            echo "⚠ Audit sink check failed"
            echo "Deployment will proceed but audit logging may be unavailable"
          }
        else
          echo "Audit sink check script not found - skipping"
          echo "To enable: create scripts/check-audit-sink.sh"
        fi

    - name: Verify image digest
      run: |
        echo "=== Verifying image digest ==="
        
        # In production, verify the image digest matches the build
        # For now, this is a placeholder
        echo "Image digest verification (placeholder)"
        echo "In production, this would verify:"
        echo "  - Image was built by the build workflow"
        echo "  - Digest matches expected value"
        echo "  - Image has not been tampered with"

  deploy:
    name: Deploy to Staging
    runs-on: self-hosted
    needs: pre-deployment-gates
    timeout-minutes: 20

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

    - name: Set up environment
      run: |
        echo "DEPLOY_ENV=${{ env.DEPLOY_ENV }}"
        echo "COMPOSE_FILE=${{ env.COMPOSE_FILE }}"
        
        # Ensure environment file exists
        if [ ! -f "deployments/.env.staging" ]; then
          echo "Creating staging environment file..."
          cat > deployments/.env.staging << 'EOF'
DATA_DIR=./data/staging
LOG_LEVEL=info
COMPLIANCE_MODE=standard
EOF
        fi

    - name: Deploy to staging
      run: |
        echo "=== Deploying to staging environment ==="
        
        # Change to deployments directory
        cd deployments
        
        # Source the environment file
        set -a
        source .env.staging
        set +a
        
        # Pull latest images
        docker compose -f docker-compose.staging.yml pull || {
          echo "⚠ Image pull failed - may be using local build"
        }
        
        # Deploy the stack
        docker compose -f docker-compose.staging.yml up -d
        
        echo "✓ Staging deployment initiated"

    - name: Post-deployment health check
      run: |
        echo "=== Running post-deployment health checks ==="
        
        # Wait for services to start
        sleep 10
        
        # Check if services are running
        cd deployments
        docker compose -f docker-compose.staging.yml ps
        
        # Check health endpoints
        echo "Checking API health..."
        curl -fsS http://localhost:9101/health || {
          echo "⚠ API health check failed - service may still be starting"
        }
        
        # Check compliance_mode
        echo "Checking compliance_mode..."
        COMPLIANCE_MODE=$(curl -fsS http://localhost:9101/health 2>/dev/null | grep -o '"compliance_mode":"[^"]*"' | cut -d'"' -f4 || echo "unknown")
        echo "Compliance mode reported: $COMPLIANCE_MODE"
        
        # Verify it matches expected
        EXPECTED_MODE=$(grep "compliance_mode" deployments/configs/worker/docker-staging.yaml 2>/dev/null | head -1 | sed 's/.*: *//' || echo "standard")
        if [ "$COMPLIANCE_MODE" = "$EXPECTED_MODE" ]; then
          echo "✓ compliance_mode matches expected: $EXPECTED_MODE"
        else
          echo "⚠ compliance_mode mismatch: expected $EXPECTED_MODE, got $COMPLIANCE_MODE"
        fi

    - name: Run smoke tests
      run: |
        echo "=== Running staging smoke tests ==="
        
        # Wait for services to be fully ready
        sleep 15
        
        # Basic connectivity test
        curl -fsS http://localhost:9101/health && echo "✓ API is responding"
        
        # Check Redis
        docker exec ml-staging-redis redis-cli ping && echo "✓ Redis is responding"
        
        # Check worker (if running)
        if docker ps | grep -q ml-staging-worker; then
          echo "✓ Worker container is running"
        fi
        
        echo "✓ Staging smoke tests passed"

    - name: Tag successful deployment
      if: success()
      run: |
        echo "=== Tagging successful staging deployment ==="
        
        # Tag the image as 'staging' after successful deployment
        cd deployments
        
        # Create a deployment marker
        echo "$(date -Iseconds) - Deployment ${{ gitea.run_id }} successful" >> .staging-deployment.log
        
        echo "✓ Staging deployment tagged as successful"

    - name: Rollback on failure
      if: failure()
      run: |
        echo "=== Deployment failed - initiating rollback ==="
        
        cd deployments
        
        # Attempt to restore previous deployment
        if [ -f ".staging-deployment.log" ]; then
          echo "Previous deployment log found - attempting rollback"
          
          # In production, this would:
          # 1. Get previous image tag from log
          # 2. Pull previous image
          # 3. Restart with previous image
          
          echo "Rollback placeholder - manual intervention may be required"
        fi
        
        # Write audit log entry
        echo "$(date -Iseconds) - Deployment ${{ gitea.run_id }} failed, rollback initiated" >> .staging-deployment.log
        
        # Still exit with failure
        exit 1
