# Post-Deploy Verification (T-13, P-005 Compliant)
#
# Runs after successful deployment to verify the live system is healthy.
# Can be triggered manually or automatically after deploy.

name: Post-Deploy Verification

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment to verify'
        required: true
        type: choice
        options:
          - production
          - staging
      base_url:
        description: 'Base URL to test (optional override)'
        required: false
        type: string

permissions:
  contents: read
  checks: write

env:
  PRODUCTION_URL: "https://llmhosts.com"
  STAGING_URL: "https://staging.llmhosts.com"

jobs:
  health-checks:
    name: Health & Readiness Checks
    runs-on: ubuntu-latest
    steps:
      - name: Determine target URL
        id: url
        run: |
          if [ -n "${{ inputs.base_url }}" ]; then
            echo "target=${{ inputs.base_url }}" >> $GITHUB_OUTPUT
          elif [ "${{ inputs.environment }}" = "production" ]; then
            echo "target=${{ env.PRODUCTION_URL }}" >> $GITHUB_OUTPUT
          else
            echo "target=${{ env.STAGING_URL }}" >> $GITHUB_OUTPUT
          fi

      - name: Check /health endpoint
        run: |
          URL="${{ steps.url.outputs.target }}/health"
          echo "Testing: $URL"

          RESPONSE=$(curl -s -w "\n%{http_code}" "$URL")
          HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
          BODY=$(echo "$RESPONSE" | head -n-1)

          echo "HTTP Status: $HTTP_CODE"
          echo "Response Body: $BODY"

          if [ "$HTTP_CODE" -ne 200 ]; then
            echo "::error::/health check failed with status $HTTP_CODE"
            exit 1
          fi

          # Verify response contains "status" field
          if ! echo "$BODY" | grep -q "status"; then
            echo "::error::/health response missing 'status' field"
            exit 1
          fi

          echo "::notice::/health check passed"

      - name: Check /ready endpoint
        run: |
          URL="${{ steps.url.outputs.target }}/ready"
          echo "Testing: $URL"

          RESPONSE=$(curl -s -w "\n%{http_code}" "$URL")
          HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
          BODY=$(echo "$RESPONSE" | head -n-1)

          echo "HTTP Status: $HTTP_CODE"
          echo "Response Body: $BODY"

          if [ "$HTTP_CODE" -ne 200 ]; then
            echo "::error::/ready check failed with status $HTTP_CODE"
            exit 1
          fi

          echo "::notice::/ready check passed"

      - name: Check frontend loads
        run: |
          URL="${{ steps.url.outputs.target }}"
          echo "Testing: $URL"

          RESPONSE=$(curl -s -w "\n%{http_code}" "$URL")
          HTTP_CODE=$(echo "$RESPONSE" | tail -n1)

          echo "HTTP Status: $HTTP_CODE"

          if [ "$HTTP_CODE" -ne 200 ]; then
            echo "::error::Frontend failed to load with status $HTTP_CODE"
            exit 1
          fi

          echo "::notice::Frontend loads successfully"

      - name: Check API docs
        run: |
          URL="${{ steps.url.outputs.target }}/docs"
          echo "Testing: $URL"

          RESPONSE=$(curl -s -w "\n%{http_code}" "$URL")
          HTTP_CODE=$(echo "$RESPONSE" | tail -n1)

          echo "HTTP Status: $HTTP_CODE"

          if [ "$HTTP_CODE" -ne 200 ]; then
            echo "::error::API docs failed to load with status $HTTP_CODE"
            exit 1
          fi

          echo "::notice::API docs accessible"

  smoke-tests:
    name: Smoke Tests
    runs-on: ubuntu-latest
    needs: [health-checks]
    steps:
      - uses: actions/checkout@v6

      - name: Determine target URL
        id: url
        run: |
          if [ -n "${{ inputs.base_url }}" ]; then
            echo "target=${{ inputs.base_url }}" >> $GITHUB_OUTPUT
          elif [ "${{ inputs.environment }}" = "production" ]; then
            echo "target=${{ env.PRODUCTION_URL }}" >> $GITHUB_OUTPUT
          else
            echo "target=${{ env.STAGING_URL }}" >> $GITHUB_OUTPUT
          fi

      - name: Test /v1/models endpoint (unauthenticated)
        run: |
          URL="${{ steps.url.outputs.target }}/v1/models"
          echo "Testing: $URL"

          RESPONSE=$(curl -s -w "\n%{http_code}" "$URL")
          HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
          BODY=$(echo "$RESPONSE" | head -n-1)

          echo "HTTP Status: $HTTP_CODE"
          echo "Response Body: $BODY"

          # Should return 401 or 403 (unauthorized) or 200 if public
          if [ "$HTTP_CODE" -ne 401 ] && [ "$HTTP_CODE" -ne 403 ] && [ "$HTTP_CODE" -ne 200 ]; then
            echo "::error::/v1/models returned unexpected status $HTTP_CODE"
            exit 1
          fi

          echo "::notice::/v1/models endpoint responding correctly"

      - name: Test rate limiting
        run: |
          URL="${{ steps.url.outputs.target }}/health"
          echo "Testing rate limits with rapid requests to: $URL"

          # Make 10 rapid requests
          for i in {1..10}; do
            curl -s -o /dev/null -w "%{http_code}\n" "$URL"
          done

          echo "::notice::Rate limiting test completed (check logs for 429 status)"

  ssl-verification:
    name: SSL/TLS Verification
    runs-on: ubuntu-latest
    needs: [health-checks]
    if: inputs.environment == 'production'
    steps:
      - name: Determine target URL
        id: url
        run: |
          if [ -n "${{ inputs.base_url }}" ]; then
            echo "target=${{ inputs.base_url }}" >> $GITHUB_OUTPUT
          else
            echo "target=${{ env.PRODUCTION_URL }}" >> $GITHUB_OUTPUT
          fi

      - name: Check SSL certificate
        run: |
          # Extract domain from URL
          DOMAIN=$(echo "${{ steps.url.outputs.target }}" | sed -e 's|^https://||' -e 's|/.*||')
          echo "Checking SSL for: $DOMAIN"

          # Get certificate expiry
          EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
          echo "Certificate expires: $EXPIRY"

          # Check if expiring within 30 days
          EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
          NOW_EPOCH=$(date +%s)
          DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

          echo "Days until expiry: $DAYS_LEFT"

          if [ $DAYS_LEFT -lt 30 ]; then
            echo "::warning::SSL certificate expires in $DAYS_LEFT days"
          fi

          if [ $DAYS_LEFT -lt 7 ]; then
            echo "::error::SSL certificate expires in $DAYS_LEFT days - URGENT renewal needed"
            exit 1
          fi

          echo "::notice::SSL certificate valid for $DAYS_LEFT days"

      - name: Test TLS configuration
        run: |
          DOMAIN=$(echo "${{ steps.url.outputs.target }}" | sed -e 's|^https://||' -e 's|/.*||')

          # Check TLS version support
          echo "Testing TLS 1.2 support..."
          if openssl s_client -connect "$DOMAIN:443" -tls1_2 </dev/null 2>/dev/null | grep -q "Cipher"; then
            echo "✓ TLS 1.2 supported"
          fi

          echo "Testing TLS 1.3 support..."
          if openssl s_client -connect "$DOMAIN:443" -tls1_3 </dev/null 2>/dev/null | grep -q "Cipher"; then
            echo "✓ TLS 1.3 supported"
          fi

          echo "::notice::TLS configuration verified"

  verify-summary:
    name: Verification Summary
    runs-on: ubuntu-latest
    needs: [health-checks, smoke-tests, ssl-verification]
    if: always()
    steps:
      - name: Generate summary
        run: |
          echo "## Post-Deploy Verification Report" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Environment:** ${{ inputs.environment }}" >> $GITHUB_STEP_SUMMARY
          echo "**Target URL:** ${{ inputs.base_url || (inputs.environment == 'production' && env.PRODUCTION_URL || env.STAGING_URL) }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
          echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY

          HEALTH_RESULT="${{ needs.health-checks.result }}"
          SMOKE_RESULT="${{ needs.smoke-tests.result }}"
          SSL_RESULT="${{ needs.ssl-verification.result }}"

          ALL_PASS=true

          if [ "$HEALTH_RESULT" = "success" ]; then
            echo "| Health & Readiness | ✅ passed |" >> $GITHUB_STEP_SUMMARY
          else
            echo "| Health & Readiness | ❌ $HEALTH_RESULT |" >> $GITHUB_STEP_SUMMARY
            ALL_PASS=false
          fi

          if [ "$SMOKE_RESULT" = "success" ]; then
            echo "| Smoke Tests | ✅ passed |" >> $GITHUB_STEP_SUMMARY
          else
            echo "| Smoke Tests | ❌ $SMOKE_RESULT |" >> $GITHUB_STEP_SUMMARY
            ALL_PASS=false
          fi

          if [ "$SSL_RESULT" = "success" ] || [ "$SSL_RESULT" = "skipped" ]; then
            echo "| SSL/TLS Verification | ✅ $SSL_RESULT |" >> $GITHUB_STEP_SUMMARY
          else
            echo "| SSL/TLS Verification | ❌ $SSL_RESULT |" >> $GITHUB_STEP_SUMMARY
            ALL_PASS=false
          fi

          echo "" >> $GITHUB_STEP_SUMMARY

          if [ "$ALL_PASS" = "true" ]; then
            echo "**Result: ✅ Deployment verified successfully**" >> $GITHUB_STEP_SUMMARY
            echo "::notice::Post-deploy verification passed"
          else
            echo "**Result: ❌ Verification failed - investigate immediately**" >> $GITHUB_STEP_SUMMARY
            echo "::error::Post-deploy verification failed"
            exit 1
          fi
