name: Backend Tests

on:
  workflow_dispatch:
  workflow_call:
    inputs:
      send_notification:
        description: "Whether to send Discord notification"
        type: boolean
        default: true
    secrets:
      WEBHOOK_URL:
        description: "Discord webhook URL"
        required: false
    outputs:
      success:
        description: "Whether tests passed"
        value: ${{ jobs.test.outputs.success }}
      total:
        description: "Total number of tests"
        value: ${{ jobs.test.outputs.total }}
      passed:
        description: "Number of passed tests"
        value: ${{ jobs.test.outputs.passed }}
      failed:
        description: "Number of failed tests"
        value: ${{ jobs.test.outputs.failed }}
      duration:
        description: "Test duration in seconds"
        value: ${{ jobs.test.outputs.duration }}

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    outputs:
      success: ${{ steps.test-results.outputs.success }}
      total: ${{ steps.test-results.outputs.total }}
      passed: ${{ steps.test-results.outputs.passed }}
      failed: ${{ steps.test-results.outputs.failed }}
      duration: ${{ steps.test-results.outputs.duration }}
      test_files: ${{ steps.test-results.outputs.test_files }}
      test_files_passed: ${{ steps.test-results.outputs.test_files_passed }}
      test_files_failed: ${{ steps.test-results.outputs.test_files_failed }}

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

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        id: run-tests
        continue-on-error: true
        run: |
          START_TIME=$(date +%s)
          npm test 2>&1 | tee test-output.txt
          TEST_EXIT_CODE=${PIPESTATUS[0]}
          END_TIME=$(date +%s)
          echo "exit_code=$TEST_EXIT_CODE" >> $GITHUB_OUTPUT
          echo "start_time=$(date -u +"%H:%M:%S")" >> $GITHUB_OUTPUT
          echo "elapsed=$((END_TIME - START_TIME))" >> $GITHUB_OUTPUT

      - name: Parse test results
        id: test-results
        if: always()
        run: |
          # Parse the test output from vitest's default reporter
          if [ -f test-output.txt ]; then
            # Strip ANSI color codes for reliable parsing
            sed -i 's/\x1b\[[0-9;]*m//g' test-output.txt
            
            # Debug: show relevant lines
            echo "=== Relevant test output lines ==="
            grep -E "(Test Files|Tests|Duration)" test-output.txt | tail -5 || true
            echo "==================================="
            
            # Extract test file count (e.g., "Test Files  81 passed (81)")
            TEST_FILES_LINE=$(grep "Test Files" test-output.txt | tail -1 || echo "")
            if [ -n "$TEST_FILES_LINE" ]; then
              TEST_FILES_PASSED=$(echo "$TEST_FILES_LINE" | grep -oE "[0-9]+ passed" | grep -oE "[0-9]+" | head -1 || echo "0")
              TEST_FILES_FAILED=$(echo "$TEST_FILES_LINE" | grep -oE "[0-9]+ failed" | grep -oE "[0-9]+" | head -1 || echo "0")
              TEST_FILES=$(echo "$TEST_FILES_LINE" | grep -oE "\([0-9]+\)" | grep -oE "[0-9]+" | head -1 || echo "0")
            else
              TEST_FILES_PASSED=0
              TEST_FILES_FAILED=0
              TEST_FILES=0
            fi
            
            # Extract test count - look for line containing "Tests" followed by number, exclude "Test Files"
            TESTS_LINE=$(grep -E "Tests\s+[0-9]+" test-output.txt | grep -v "Test Files" | tail -1 || echo "")
            if [ -n "$TESTS_LINE" ]; then
              PASSED=$(echo "$TESTS_LINE" | grep -oE "[0-9]+ passed" | grep -oE "[0-9]+" | head -1 || echo "0")
              FAILED=$(echo "$TESTS_LINE" | grep -oE "[0-9]+ failed" | grep -oE "[0-9]+" | head -1 || echo "0")
              TOTAL=$(echo "$TESTS_LINE" | grep -oE "\([0-9]+\)" | grep -oE "[0-9]+" | head -1 || echo "0")
            else
              PASSED=0
              FAILED=0
              TOTAL=0
            fi
            
            # Extract duration (e.g., "Duration  26.97s")
            DURATION_LINE=$(grep -E "Duration\s+[0-9]+" test-output.txt | tail -1 || echo "")
            if [ -n "$DURATION_LINE" ]; then
              DURATION=$(echo "$DURATION_LINE" | grep -oE "[0-9]+\.[0-9]+s" | head -1 | sed 's/s//' || echo "0")
            else
              DURATION="${{ steps.run-tests.outputs.elapsed }}"
            fi
            
            # Determine success based on exit code and failed count
            if [ "${{ steps.run-tests.outputs.exit_code }}" = "0" ] && [ "${FAILED:-0}" = "0" ]; then
              SUCCESS="true"
            else
              SUCCESS="false"
            fi
          else
            TOTAL=0
            PASSED=0
            FAILED=1
            TEST_FILES=0
            TEST_FILES_PASSED=0
            TEST_FILES_FAILED=1
            DURATION=0
            SUCCESS="false"
          fi
          
          # Set defaults for empty values
          TOTAL=${TOTAL:-0}
          PASSED=${PASSED:-0}
          FAILED=${FAILED:-0}
          TEST_FILES=${TEST_FILES:-0}
          TEST_FILES_PASSED=${TEST_FILES_PASSED:-0}
          TEST_FILES_FAILED=${TEST_FILES_FAILED:-0}
          DURATION=${DURATION:-0}
          
          echo "=== Parsed values ==="
          echo "TEST_FILES_PASSED=$TEST_FILES_PASSED"
          echo "TEST_FILES=$TEST_FILES"
          echo "PASSED=$PASSED"
          echo "TOTAL=$TOTAL"
          echo "DURATION=$DURATION"
          echo "SUCCESS=$SUCCESS"
          echo "===================="
          
          echo "total=$TOTAL" >> $GITHUB_OUTPUT
          echo "passed=$PASSED" >> $GITHUB_OUTPUT
          echo "failed=$FAILED" >> $GITHUB_OUTPUT
          echo "duration=$DURATION" >> $GITHUB_OUTPUT
          echo "success=$SUCCESS" >> $GITHUB_OUTPUT
          echo "test_files=$TEST_FILES" >> $GITHUB_OUTPUT
          echo "test_files_passed=$TEST_FILES_PASSED" >> $GITHUB_OUTPUT
          echo "test_files_failed=$TEST_FILES_FAILED" >> $GITHUB_OUTPUT
          
          echo "## 🧪 Test Results" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          if [ "$SUCCESS" = "true" ]; then
            echo "### ✅ All tests passed!" >> $GITHUB_STEP_SUMMARY
          else
            echo "### ❌ Some tests failed" >> $GITHUB_STEP_SUMMARY
          fi
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
          echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
          echo "| Test Files | $TEST_FILES_PASSED passed ($TEST_FILES) |" >> $GITHUB_STEP_SUMMARY
          echo "| Tests | $PASSED passed ($TOTAL) |" >> $GITHUB_STEP_SUMMARY
          echo "| Duration | ${DURATION}s |" >> $GITHUB_STEP_SUMMARY

      - name: Send Discord notification
        if: always() && (inputs.send_notification != false)
        env:
          WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
        run: |
          if [ -z "$WEBHOOK_URL" ]; then
            echo "No webhook URL provided, skipping notification"
            exit 0
          fi
          
          SUCCESS="${{ steps.test-results.outputs.success }}"
          TOTAL="${{ steps.test-results.outputs.total }}"
          PASSED="${{ steps.test-results.outputs.passed }}"
          FAILED="${{ steps.test-results.outputs.failed }}"
          DURATION="${{ steps.test-results.outputs.duration }}"
          TEST_FILES="${{ steps.test-results.outputs.test_files }}"
          TEST_FILES_PASSED="${{ steps.test-results.outputs.test_files_passed }}"
          TEST_FILES_FAILED="${{ steps.test-results.outputs.test_files_failed }}"
          
          if [ "$SUCCESS" = "true" ]; then
            COLOR=5763719
            TITLE="✅ Tests Passed"
            DESCRIPTION="All tests completed successfully for **ReadMeABook**"
            TEST_FILES_VALUE="$TEST_FILES_PASSED passed ($TEST_FILES)"
            TESTS_VALUE="$PASSED passed ($TOTAL)"
          else
            COLOR=15548997
            TITLE="❌ Tests Failed"
            DESCRIPTION="Some tests failed for **ReadMeABook**"
            TEST_FILES_VALUE="$TEST_FILES_PASSED passed, $TEST_FILES_FAILED failed ($TEST_FILES)"
            TESTS_VALUE="$PASSED passed, $FAILED failed ($TOTAL)"
          fi
          
          curl -H "Content-Type: application/json" \
            -X POST \
            -d "{
              \"embeds\": [{
                \"title\": \"$TITLE\",
                \"description\": \"$DESCRIPTION\",
                \"color\": $COLOR,
                \"fields\": [
                  {
                    \"name\": \"📁 Test Files\",
                    \"value\": \"\`$TEST_FILES_VALUE\`\",
                    \"inline\": true
                  },
                  {
                    \"name\": \"🧪 Tests\",
                    \"value\": \"\`$TESTS_VALUE\`\",
                    \"inline\": true
                  },
                  {
                    \"name\": \"⏱️ Duration\",
                    \"value\": \"\`${DURATION}s\`\",
                    \"inline\": true
                  },
                  {
                    \"name\": \"🌿 Branch\",
                    \"value\": \"\`${{ github.ref_name }}\`\",
                    \"inline\": true
                  },
                  {
                    \"name\": \"📋 Commit\",
                    \"value\": \"[\`$(echo ${{ github.sha }} | cut -c1-7)\`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\",
                    \"inline\": true
                  },
                  {
                    \"name\": \"🔗 Workflow\",
                    \"value\": \"[View Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\",
                    \"inline\": true
                  }
                ],
                \"footer\": {
                  \"text\": \"ReadMeABook CI/CD • Test Suite\"
                },
                \"timestamp\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"
              }]
            }" \
            "$WEBHOOK_URL"

      - name: Fail if tests failed
        if: steps.test-results.outputs.success != 'true'
        run: exit 1
