name: Bazel Test

on:
  push:
    branches: [ "main" ]
    paths:
      - 'src/**'
      - 'WORKSPACE'
      - 'MODULE.bazel'
      - 'BUILD.bazel'
      - '.bazelrc'
      - '.github/workflows/bazel_test.yml'
      - '!src/main/csharp/**'
      - '!src/test/csharp/**'
  pull_request:
    paths:
      - 'src/**'
      - 'WORKSPACE'
      - 'MODULE.bazel'
      - 'BUILD.bazel'
      - '.bazelrc'
      - '.github/workflows/bazel_test.yml'
      - '!src/main/csharp/**'
      - '!src/test/csharp/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  lint:
    runs-on: [self-hosted, bazel]
    steps:
    - name: Clean workspace
      run: |
        git sparse-checkout disable 2>/dev/null || true
        git config --local core.sparseCheckout false 2>/dev/null || true
        git config --local --unset extensions.worktreeConfig 2>/dev/null || true
        rm -f .git/info/sparse-checkout .git/config.worktree 2>/dev/null || true
    - name: Checkout repository
      uses: actions/checkout@v6
      with:
        lfs: false
    - name: Check BUILD.bazel dependencies
      run: ./scripts/check_build_deps.sh --strict
    - name: Set up Node.js
      uses: actions/setup-node@v6
      with:
        node-version: 'lts/*'
    - name: Check JavaScript syntax
      run: node --check src/main/go/net/eagle0/admin_server/static/map_editor.js

  test:
    runs-on: [self-hosted, bazel]
    steps:
    - name: Clean workspace
      run: |
        git sparse-checkout disable 2>/dev/null || true
        git config --local core.sparseCheckout false 2>/dev/null || true
        git config --local --unset extensions.worktreeConfig 2>/dev/null || true
        rm -f .git/info/sparse-checkout .git/config.worktree 2>/dev/null || true
    - name: Checkout repository
      uses: actions/checkout@v6
      with:
        lfs: false
    - name: Run tests
      run: bazel test --build_event_json_file=test.json //src/test/... //src/main/go/...
    - name: Collect failed test logs
      if: always()
      run: |
        # Remove any existing failed_test_logs directory and create fresh
        rm -rf failed_test_logs
        mkdir -p failed_test_logs
        # Extract failed test targets from test.json and copy their logs
        # The test.json is in JSONL format - one JSON object per line
        # We look for lines with testResult that have a status other than PASSED
        if [ -f test.json ]; then
          grep '"testResult"' test.json | \
            grep '"status"' | \
            grep -v '"status":"PASSED"' | \
            grep -o '"label":"[^"]*"' | \
            cut -d'"' -f4 | \
            sort -u | \
            while read target; do
              # Convert target like //src/test/cpp/...:test_name to path
              log_path=$(echo "$target" | sed 's|^//||' | sed 's|:|/|')
              if [ -f "bazel-testlogs/$log_path/test.log" ]; then
                log_name=$(echo "$log_path" | tr '/' '_')
                if cp "bazel-testlogs/$log_path/test.log" "failed_test_logs/${log_name}.log"; then
                  echo "Collected log for failed test: $target"
                else
                  echo "Error: Failed to copy log for $target"
                fi
              fi
            done
        fi
        # List what we collected
        echo "Collected logs:"
        ls -lh failed_test_logs/ 2>/dev/null || echo "No logs collected"
    - name: Archive test results
      if: always()
      uses: actions/upload-artifact@v7
      with:
        name: test.json
        path: test.json
        retention-days: 3
    - name: Archive failed test logs
      if: always()
      uses: actions/upload-artifact@v7
      with:
        name: failed-test-logs
        path: failed_test_logs/
        if-no-files-found: ignore
        retention-days: 3
