name: Merge translations

on:
  workflow_dispatch:
  workflow_call:
    secrets:
      PUSH_O_MATIC_APP_ID:
        required: true
      PUSH_O_MATIC_APP_KEY:
        required: true
      WEBLATE_TOKEN:
        required: true
    inputs:
      skip:
        description: 'Skip translations'
        required: false
        type: boolean

permissions: {}

env:
  WEBLATE_HOST: 'https://hosted.weblate.org'
  WEBLATE_COMPONENT: 'immich/immich'

jobs:
  merge:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - name: Generate a token
        id: generate_token
        if: ${{ inputs.skip != true }}
        uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
        with:
          app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
          private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}

      - name: Find translation PR
        id: find_pr
        if: ${{ inputs.skip != true }}
        env:
          GH_TOKEN: ${{ steps.generate_token.outputs.token }}
        run: |
          set -euo pipefail

          PR=$(gh pr list --repo $GITHUB_REPOSITORY --author weblate --json number,mergeable)
          echo "$PR"

          PR_NUMBER=$(echo "$PR" | jq '
            if length == 1 then
              .[0].number
            else
              error("Expected exactly 1 entry, got \(length)")
            end
          ' 2>&1) || exit 1

          echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT
          echo "Selected PR $PR_NUMBER"

          if ! echo "$PR" | jq -e '.[0].mergeable == "MERGEABLE"'; then
            echo "PR is not mergeable"
            exit 1
          fi

      - name: Lock weblate
        if: ${{ inputs.skip != true }}
        env:
          WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
        run: |
          curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=true

      - name: Commit translations
        if: ${{ inputs.skip != true }}
        env:
          WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
        run: |
          curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/repository/" -d operation=commit
          curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/repository/" -d operation=push

      - name: Merge PR
        id: merge_pr
        if: ${{ inputs.skip != true }}
        env:
          GH_TOKEN: ${{ steps.generate_token.outputs.token }}
          PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }}
        run: |
          set -euo pipefail

          REVIEW_ID=$(gh api -X POST "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews" --field event='APPROVE' --field body='Automatically merging translations PR' \
            | jq '.id')
          echo "REVIEW_ID=$REVIEW_ID" >> $GITHUB_OUTPUT
          gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --auto --squash

      - name: Wait for PR to merge
        if: ${{ inputs.skip != true }}
        env:
          GH_TOKEN: ${{ steps.generate_token.outputs.token }}
          PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }}
          REVIEW_ID: ${{ steps.merge_pr.outputs.REVIEW_ID }}
        run: |
          # So we clean up no matter what
          set +e

          for i in {1..100}; do
            if gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json state | jq -e '.state == "MERGED"'; then
              echo "PR merged"
              exit 0
            else
              echo "PR not merged yet, waiting..."
              sleep 6
            fi
          done
          echo "PR did not merge in time"
          gh api -X PUT "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews/$REVIEW_ID/dismissals" --field message='Merge attempt timed out' --field event='DISMISS'
          gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --disable-auto
          exit 1

      - name: Unlock weblate
        if: ${{ inputs.skip != true }}
        env:
          WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
        run: |
          curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=false

      - name: Report success
        run: |
          echo "Workflow completed successfully (or was skipped)"
