name: Firebase Tests

on:
  schedule:
    - cron: '0 3 * * *'   # once per day at 3 AM
  workflow_dispatch:

jobs:
  check-changes:
    name: Detect Firebase-Relevant Changes
    runs-on: ubuntu-latest
    timeout-minutes: 5
    outputs:
      has_changes: ${{ steps.diff.outputs.has_changes }}

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Detect Firebase-relevant changes in last 24 hours
        id: diff
        shell: bash
        run: |
          # On workflow_dispatch always run
          if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then
            echo "has_changes=true" >> "$GITHUB_OUTPUT"
            exit 0
          fi

          SINCE=$(date -u -d '24 hours ago' '+%Y-%m-%dT%H:%M:%S')
          CHANGED=$(git log --since="$SINCE" --name-only --format= -- \
            'android/' 'integration_test/' 'lib/' 'pubspec.yaml' 'pubspec.lock' 'drift_schemas/' \
            | sort -u | grep -v '^$')

          if [ -n "$CHANGED" ]; then
            echo "Firebase-relevant files changed since $SINCE:"
            echo "$CHANGED"
            echo "has_changes=true" >> "$GITHUB_OUTPUT"
          else
            echo "No Firebase-relevant changes in the last 24 hours — skipping tests"
            echo "has_changes=false" >> "$GITHUB_OUTPUT"
          fi

  test-android-firebase:
    name: Android Instrumented Tests (Firebase Test Lab)
    runs-on: ubuntu-latest
    timeout-minutes: 60
    needs: [check-changes]
    if: needs.check-changes.outputs.has_changes == 'true'

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Check runner tools
        run: |
          command -v dagger  >/dev/null 2>&1 || { echo "ERROR: dagger is not installed in the runner image. Add it to .forgejo/Dockerfile."; exit 1; }
          command -v task    >/dev/null 2>&1 || { echo "ERROR: task is not installed in the runner image. Add it to .forgejo/Dockerfile."; exit 1; }

      - name: Setup Dagger Remote Engine
        env:
          SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
        run: scripts/setup_dagger_remote.sh

      - name: Run Android Tests on Firebase Test Lab
        env:
          FIREBASE_PROJECT_ID: ${{ vars.FIREBASE_PROJECT_ID }}
          DAGGER_NO_NAG: "1"
        run: task test-android-firebase

      - name: Create issue on test failure
        if: failure()
        env:
          FORGEJO_TOKEN: ${{ github.token }}
          FORGEJO_URL: ${{ github.server_url }}
          RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
        run: |
          python3 - << 'PYEOF'
          import os, json, urllib.request, urllib.error

          token = os.environ["FORGEJO_TOKEN"]
          url_base = os.environ["FORGEJO_URL"].rstrip("/")
          run_url = os.environ["RUN_URL"]

          headers = {"Authorization": f"token {token}", "Content-Type": "application/json"}
          api = f"{url_base}/api/v1/repos/guettli/sharedinbox"

          def api_get(path):
              req = urllib.request.Request(f"{api}{path}", headers=headers)
              with urllib.request.urlopen(req) as r:
                  return json.loads(r.read())

          def api_post(path, body):
              data = json.dumps(body).encode()
              req = urllib.request.Request(f"{api}{path}", data=data, headers=headers, method="POST")
              with urllib.request.urlopen(req) as r:
                  return json.loads(r.read())

          repo_labels = api_get("/labels")
          label_map = {l["name"]: l["id"] for l in repo_labels}

          label_ids = [label_map["Ready"]] if "Ready" in label_map else []

          title = "Firebase Tests failed — find root cause and fix"
          body = (
              "Firebase instrumented tests failed in the daily run.\n\n"
              f"**Failed run:** {run_url}\n\n"
              "## Steps to resolve\n\n"
              "1. **Find the root cause**: Check the test run logs linked above and identify which test(s) failed and why.\n"
              "2. **Fix if possible**: If the failure is caused by a code bug, create a fix. If it is a flaky or infrastructure issue, document the findings.\n"
              "3. Close this issue once the root cause is resolved and the tests pass.\n"
          )

          issue = api_post("/issues", {
              "title": title,
              "body": body,
              "labels": label_ids,
          })
          print(f"Created issue #{issue['number']}: {issue['html_url']}")
          PYEOF
