name: Uptime Monitor

on:
  schedule:
    # Run every 5 minutes
    - cron: '*/5 * * * *'
  workflow_dispatch:
    inputs:
      verbose:
        description: 'Verbose output'
        required: false
        default: false
        type: boolean

# Prevent concurrent monitoring runs
concurrency:
  group: uptime-monitor
  cancel-in-progress: true

env:
  BASE_URL: https://workroot.in
  RESPONSE_TIME_THRESHOLD_MS: 3000
  # SSL check: days before expiry to alert
  SSL_ALERT_DAYS: 14

jobs:
  # ============================================================
  # Job 1: Health & Response Time Check
  # ============================================================
  health-check:
    name: Health & Response Time
    runs-on: ubuntu-latest
    timeout-minutes: 5

    outputs:
      health-status: ${{ steps.health.outputs.status }}
      response-time: ${{ steps.health.outputs.response_time }}
      is-slow: ${{ steps.health.outputs.is_slow }}

    steps:
      - name: Check health endpoint
        id: health
        run: |
          START=$(date +%s%3N)
          HTTP_RESPONSE=$(curl \
            --silent \
            --max-time 10 \
            --write-out "\n%{http_code}" \
            "${{ env.BASE_URL }}/api/health.json" \
          )
          END=$(date +%s%3N)
          RESPONSE_TIME=$((END - START))

          HTTP_BODY=$(echo "$HTTP_RESPONSE" | head -n -1)
          HTTP_CODE=$(echo "$HTTP_RESPONSE" | tail -n 1)

          echo "HTTP status: $HTTP_CODE"
          echo "Response time: ${RESPONSE_TIME}ms"
          echo "Body: $HTTP_BODY"

          # Outputs
          echo "response_time=${RESPONSE_TIME}" >> $GITHUB_OUTPUT

          if [ "$HTTP_CODE" = "200" ]; then
            STATUS=$(echo "$HTTP_BODY" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status','unknown'))" 2>/dev/null || echo "parse-error")
            echo "status=${STATUS}" >> $GITHUB_OUTPUT
          else
            echo "status=down-${HTTP_CODE}" >> $GITHUB_OUTPUT
          fi

          # Slow response check
          if [ "$RESPONSE_TIME" -gt "${{ env.RESPONSE_TIME_THRESHOLD_MS }}" ]; then
            echo "is_slow=true" >> $GITHUB_OUTPUT
            echo "WARNING: Response time ${RESPONSE_TIME}ms exceeds threshold ${{ env.RESPONSE_TIME_THRESHOLD_MS }}ms"
          else
            echo "is_slow=false" >> $GITHUB_OUTPUT
          fi

      - name: Check critical pages
        id: pages
        run: |
          FAILED_PAGES=""
          PAGES="/ /services /portfolio /contact /about"

          for PAGE in $PAGES; do
            START=$(date +%s%3N)
            HTTP_CODE=$(curl --silent --max-time 10 -o /dev/null -w "%{http_code}" "${{ env.BASE_URL }}${PAGE}")
            END=$(date +%s%3N)
            RT=$((END - START))

            if [ "$HTTP_CODE" != "200" ]; then
              FAILED_PAGES="${FAILED_PAGES} ${PAGE}(${HTTP_CODE})"
              echo "FAIL: ${PAGE} → HTTP $HTTP_CODE"
            else
              echo "OK:   ${PAGE} → HTTP $HTTP_CODE (${RT}ms)"
            fi
          done

          if [ -n "$FAILED_PAGES" ]; then
            echo "Failed pages:${FAILED_PAGES}"
            exit 1
          fi

      - name: Check sitemap and robots.txt
        run: |
          for RESOURCE in "/sitemap.xml" "/robots.txt"; do
            HTTP_CODE=$(curl --silent --max-time 10 -o /dev/null -w "%{http_code}" "${{ env.BASE_URL }}${RESOURCE}")
            if [ "$HTTP_CODE" != "200" ]; then
              echo "FAIL: ${RESOURCE} returned HTTP $HTTP_CODE"
              exit 1
            fi
            echo "OK: ${RESOURCE} → HTTP $HTTP_CODE"
          done

  # ============================================================
  # Job 2: SSL Certificate Check
  # ============================================================
  ssl-check:
    name: SSL Certificate
    runs-on: ubuntu-latest
    timeout-minutes: 5

    outputs:
      days-until-expiry: ${{ steps.ssl.outputs.days_until_expiry }}
      ssl-valid: ${{ steps.ssl.outputs.ssl_valid }}

    steps:
      - name: Check SSL certificate
        id: ssl
        run: |
          DOMAIN="workroot.in"

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

          if [ -z "$EXPIRY" ]; then
            echo "ssl_valid=false" >> $GITHUB_OUTPUT
            echo "days_until_expiry=0" >> $GITHUB_OUTPUT
            echo "ERROR: Could not retrieve SSL certificate"
            exit 1
          fi

          EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || date -j -f "%b %d %H:%M:%S %Y %Z" "$EXPIRY" +%s 2>/dev/null)
          NOW_EPOCH=$(date +%s)
          DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

          echo "ssl_valid=true" >> $GITHUB_OUTPUT
          echo "days_until_expiry=${DAYS_LEFT}" >> $GITHUB_OUTPUT

          echo "SSL certificate expires: $EXPIRY"
          echo "Days until expiry: $DAYS_LEFT"

          if [ "$DAYS_LEFT" -le "${{ env.SSL_ALERT_DAYS }}" ]; then
            echo "WARNING: SSL certificate expires in $DAYS_LEFT days!"
            exit 1
          fi

          echo "SSL OK: $DAYS_LEFT days remaining"

  # ============================================================
  # Job 3: Alert on Downtime or Issues
  # ============================================================
  alert:
    name: Send Alerts
    runs-on: ubuntu-latest
    timeout-minutes: 5
    needs: [health-check, ssl-check]
    if: |
      always() &&
      (
        needs.health-check.result == 'failure' ||
        needs.ssl-check.result == 'failure' ||
        needs.health-check.outputs.health-status != 'ok' ||
        needs.health-check.outputs.is-slow == 'true'
      )

    steps:
      - name: Build alert summary
        id: alert-content
        run: |
          HEALTH_STATUS="${{ needs.health-check.outputs.health-status }}"
          RESPONSE_TIME="${{ needs.health-check.outputs.response-time }}"
          IS_SLOW="${{ needs.health-check.outputs.is-slow }}"
          SSL_DAYS="${{ needs.ssl-check.outputs.days-until-expiry }}"
          SSL_VALID="${{ needs.ssl-check.outputs.ssl-valid }}"

          # Determine alert type
          if [ "${{ needs.health-check.result }}" = "failure" ]; then
            ALERT_TYPE="DOWNTIME"
            SEVERITY="critical"
          elif [ "$IS_SLOW" = "true" ]; then
            ALERT_TYPE="SLOW_RESPONSE"
            SEVERITY="warning"
          elif [ "${{ needs.ssl-check.result }}" = "failure" ]; then
            ALERT_TYPE="SSL_EXPIRY"
            SEVERITY="warning"
          else
            ALERT_TYPE="DEGRADED"
            SEVERITY="warning"
          fi

          echo "alert_type=${ALERT_TYPE}" >> $GITHUB_OUTPUT
          echo "severity=${SEVERITY}" >> $GITHUB_OUTPUT

          # GitHub Step Summary
          echo "## Alert: ${ALERT_TYPE} [${SEVERITY^^}]" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
          echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
          echo "| Health Status | ${HEALTH_STATUS} |" >> $GITHUB_STEP_SUMMARY
          echo "| Response Time | ${RESPONSE_TIME}ms |" >> $GITHUB_STEP_SUMMARY
          echo "| Response Slow | ${IS_SLOW} |" >> $GITHUB_STEP_SUMMARY
          echo "| SSL Valid | ${SSL_VALID} |" >> $GITHUB_STEP_SUMMARY
          echo "| SSL Days Left | ${SSL_DAYS} |" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Time:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
          echo "**Site:** ${{ env.BASE_URL }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "[View Health Endpoint](${{ env.BASE_URL }}/api/health.json)" >> $GITHUB_STEP_SUMMARY

      # ── Slack notification (enable by adding SLACK_WEBHOOK_URL secret) ──
      # - name: Notify Slack
      #   if: secrets.SLACK_WEBHOOK_URL != ''
      #   run: |
      #     ALERT_TYPE="${{ steps.alert-content.outputs.alert_type }}"
      #     SEVERITY="${{ steps.alert-content.outputs.severity }}"
      #     COLOR=$([ "$SEVERITY" = "critical" ] && echo "danger" || echo "warning")
      #     EMOJI=$([ "$SEVERITY" = "critical" ] && echo ":red_circle:" || echo ":warning:")
      #
      #     curl -s -X POST "${{ secrets.SLACK_WEBHOOK_URL }}" \
      #       -H 'Content-type: application/json' \
      #       --data "{
      #         \"text\": \"${EMOJI} WorkRoot Alert: ${ALERT_TYPE}\",
      #         \"attachments\": [{
      #           \"color\": \"${COLOR}\",
      #           \"fields\": [
      #             {\"title\": \"Alert\", \"value\": \"${ALERT_TYPE}\", \"short\": true},
      #             {\"title\": \"Site\", \"value\": \"${{ env.BASE_URL }}\", \"short\": true},
      #             {\"title\": \"Response Time\", \"value\": \"${{ needs.health-check.outputs.response-time }}ms\", \"short\": true},
      #             {\"title\": \"SSL Days Left\", \"value\": \"${{ needs.ssl-check.outputs.days-until-expiry }}\", \"short\": true}
      #           ],
      #           \"footer\": \"WorkRoot Monitor | $(date -u '+%Y-%m-%d %H:%M UTC')\"
      #         }]
      #       }"

      # ── Email/PagerDuty notification (via webhook) ──
      # - name: Notify via webhook
      #   if: secrets.ALERT_WEBHOOK_URL != ''
      #   run: |
      #     curl -s -X POST "${{ secrets.ALERT_WEBHOOK_URL }}" \
      #       -H 'Content-type: application/json' \
      #       --data '{
      #         "event": "${{ steps.alert-content.outputs.alert_type }}",
      #         "severity": "${{ steps.alert-content.outputs.severity }}",
      #         "site": "${{ env.BASE_URL }}",
      #         "health_status": "${{ needs.health-check.outputs.health-status }}",
      #         "response_time_ms": "${{ needs.health-check.outputs.response-time }}",
      #         "ssl_days_left": "${{ needs.ssl-check.outputs.days-until-expiry }}",
      #         "timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
      #       }'

      - name: Fail workflow to make alert visible
        run: |
          echo "Alert triggered: ${{ steps.alert-content.outputs.alert_type }}"
          echo "Severity: ${{ steps.alert-content.outputs.severity }}"
          exit 1

  # ============================================================
  # Job 4: Record Success (for uptime tracking)
  # ============================================================
  record-success:
    name: Record Uptime Success
    runs-on: ubuntu-latest
    timeout-minutes: 2
    needs: [health-check, ssl-check]
    if: |
      always() &&
      needs.health-check.result == 'success' &&
      needs.ssl-check.result == 'success'

    steps:
      - name: Log success
        run: |
          echo "## Uptime Check Passed" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Check | Result |" >> $GITHUB_STEP_SUMMARY
          echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
          echo "| Health | ${{ needs.health-check.outputs.health-status }} |" >> $GITHUB_STEP_SUMMARY
          echo "| Response Time | ${{ needs.health-check.outputs.response-time }}ms |" >> $GITHUB_STEP_SUMMARY
          echo "| SSL Days Left | ${{ needs.ssl-check.outputs.days-until-expiry }} |" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Checked at:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
