name: Pull Request CI

on:
  pull_request:
    branches: [ main ]

permissions:
  contents: read

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

jobs:
  # 1. CHANGE DETECTION: Prevents unnecessary builds
  check-changes:
    if: github.repository == 'meshtastic/Meshtastic-Android' && !( github.head_ref == 'scheduled-updates' || github.head_ref == 'l10n_main' )
    runs-on: ubuntu-24.04-arm
    outputs:
      android: ${{ steps.filter.outputs.android }}
    steps:
      - uses: actions/checkout@v6
      - uses: dorny/paths-filter@v4
        id: filter
        with:
          token: ''
          filters: |
            android:
              # CI/workflow implementation
              - '.github/workflows/**'
              - '.github/actions/**'
              # Product modules validated by reusable-check
              - 'app/**'
              - 'baselineprofile/**'
              - 'desktop/**'
              - 'core/**'
              - 'feature/**'
              # Shared build infrastructure
              - 'build-logic/**'
              - 'config/**'
              - 'gradle/**'
              # Root build entrypoints/config that can alter task graph or outputs
              - 'build.gradle.kts'
              - 'config.properties'
              - 'compose_compiler_config.conf'
              - 'gradle.properties'
              - 'gradlew'
              - 'gradlew.bat'
              - 'settings.gradle.kts'
              - 'test.gradle.kts'

  # 1b. FILTER DRIFT CHECK: Ensures check-changes stays aligned with module roots
  verify-check-changes-filter:
    if: github.repository == 'meshtastic/Meshtastic-Android' && !( github.head_ref == 'scheduled-updates' || github.head_ref == 'l10n_main' )
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@v6
      - name: Verify module roots are represented in check-changes filter
        run: |
          python3 - <<'PY'
          import re
          from pathlib import Path

          settings = Path('settings.gradle.kts').read_text()
          workflow = Path('.github/workflows/pull-request.yml').read_text()

          module_roots = {
              module.split(':')[0]
              for module in re.findall(r'":([^"]+)"', settings)
          }

          allowed_extra_roots = {'baselineprofile'}
          expected_roots = module_roots | allowed_extra_roots

          filter_paths = {
              path.split('/')[0]
              for path in re.findall(r"-\s*'([^']+/\*\*)'", workflow)
          }

          actual_module_roots = filter_paths & expected_roots

          missing = sorted(expected_roots - actual_module_roots)
          unexpected = sorted(actual_module_roots - expected_roots)

          if missing or unexpected:
              print('check-changes filter drift detected:')
              if missing:
                  print('  Missing roots:', ', '.join(missing))
              if unexpected:
                  print('  Unexpected roots:', ', '.join(unexpected))
              raise SystemExit(1)

          print('check-changes filter is aligned with settings.gradle module roots.')
          PY

  # 2. VALIDATION & BUILD: Delegate to reusable-check.yml
  # We disable coverage and desktop builds for PRs to keep feedback fast
  # (< 10 mins). Desktop compilation is already covered by the :desktop:test
  # task in the shard-app test shard.
  validate-and-build:
    needs: check-changes
    if: needs.check-changes.outputs.android == 'true'
    uses: ./.github/workflows/reusable-check.yml
    with:
      run_lint: true
      run_unit_tests: true
      run_coverage: false
      run_desktop_builds: false
      upload_artifacts: true
    secrets: inherit

  # 3. WORKFLOW STATUS: Ensures required checks are satisfied
  check-workflow-status:
    name: Check Workflow Status
    runs-on: ubuntu-24.04-arm
    permissions: {}
    needs: [check-changes, verify-check-changes-filter, validate-and-build]
    if: always()
    steps:
      - name: Check Workflow Status
        run: |
          if [[ "${{ needs.verify-check-changes-filter.result }}" == "failure" || "${{ needs.verify-check-changes-filter.result }}" == "cancelled" ]]; then
            echo "::error::check-changes filter verification failed"
            exit 1
          fi

          # If changes were detected but build failed, fail the status check
          if [[ "${{ needs.check-changes.outputs.android }}" == "true" && ("${{ needs.validate-and-build.result }}" == "failure" || "${{ needs.validate-and-build.result }}" == "cancelled") ]]; then
            echo "::error::Android Check failed"
            exit 1
          fi
          
          # If no changes were detected, this still succeeds to satisfy required status check
          echo "Workflow status satisfied."
