name: Tests

on:
  push:
    branches:
      - main
    paths-ignore:
      - "package.json"
      - "package-lock.json"
  pull_request:
    branches:
      - main
    paths:
      - 'internal/**'
      - 'cmd/**'
      - 'test/**'
      - go.mod
      - go.sum
      - 'mise.toml'


permissions:
  contents: read
  pull-requests: write

jobs:
  unit-tests:
    name: Unit Tests
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up tools
        uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4

      - name: Cache Go modules
        uses: actions/cache@v4
        with:
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: ${{ runner.os }}-go-

      - name: Run unit tests
        run: mise run test:unit

      - name: Upload unit test coverage
        uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
        with:
          files: ./coverage-unit.out
          flags: unit
          name: unit-tests

  integration-tests:
    name: Integration Tests
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up tools
        uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4

      - name: Cache Go modules
        uses: actions/cache@v4
        with:
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: ${{ runner.os }}-go-

      - name: Run integration tests
        run: mise run test:integration

      - name: Check coverage file has data
        id: check-coverage
        run: |
          # Check if coverage file has more than just the mode line
          if [ -f ./coverage-integration.out ] && [ $(wc -l < ./coverage-integration.out) -gt 1 ]; then
            echo "has_coverage=true" >> $GITHUB_OUTPUT
          else
            echo "has_coverage=false" >> $GITHUB_OUTPUT
            echo "⚠️ Coverage file is empty or missing, skipping upload"
          fi

      - name: Upload integration test coverage
        if: steps.check-coverage.outputs.has_coverage == 'true'
        uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
        with:
          files: ./coverage-integration.out
          flags: integration
          name: integration-tests

  e2e-tests:
    name: E2E Tests
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up tools
        uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4

      - name: Cache Go modules
        uses: actions/cache@v4
        with:
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: ${{ runner.os }}-go-

      - name: Run e2e tests
        run: mise run test:e2e
        timeout-minutes: 15

  test-summary:
    name: Test Summary
    runs-on: ubuntu-latest
    needs: [unit-tests, integration-tests, e2e-tests]
    if: always()

    steps:
      - name: Check test results
        run: |
          if [ "${{ needs.unit-tests.result }}" != "success" ] || [ "${{ needs.integration-tests.result }}" != "success" ] || [ "${{ needs.e2e-tests.result }}" != "success" ]; then
            echo "❌ Tests failed"
            exit 1
          fi
          echo "✅ All tests passed"
