name: PROpenedOrUpdated
run-name: "PR ${{github.event.number}} ${{github.event.action}} by ${{ github.actor }}"
on:
#  workflow_dispatch:
  pull_request_target:
    types: [opened, reopened, synchronize]

env:
  ASTERISK_REPO:     ${{github.repository}}
  PR_NUMBER:         ${{github.event.number}}
  PR_COMMIT:         ${{github.event.pull_request.head.sha}}
  BRANCH:            ${{github.event.pull_request.base.ref}}
  GITHUB_TOKEN:      ${{secrets.GITHUB_TOKEN}}
  MODULES_BLACKLIST: ${{vars.GATETEST_MODULES_BLACKLIST}} ${{vars.UNITTEST_MODULES_BLACKLIST}}

jobs:

  PROpenUpdateUnitTests:
    runs-on: ubuntu-latest
    steps:
      - name: Job Start Delay
        env:
          JOB_START_DELAY_SEC:       ${{vars.PR_JOB_START_DELAY_SEC}}
        run: |
          # Give the user a chance to add their "cherry-pick-to" comments
          sleep ${JOB_START_DELAY_SEC:-60}

      - name: Get Token needed to add reviewers
        if: github.event.action == 'opened'
        id: get_workflow_token
        uses: peter-murray/workflow-application-token-action@v2
        with:
          application_id: ${{secrets.ASTERISK_ORG_ACCESS_APP_ID}}
          application_private_key: ${{secrets.ASTERISK_ORG_ACCESS_APP_PRIV_KEY}}
          organization: asterisk

      - name: Get cherry-pick branches
        uses: asterisk/asterisk-ci-actions/GetCherryPickBranchesFromPR@main
        id: getbranches
        with:
          repo:                    ${{github.repository}}
          pr_number:               ${{env.PR_NUMBER}}
          cherry_pick_regex:       ${{vars.CHERRY_PICK_REGEX}}
          github_token:            ${{secrets.GITHUB_TOKEN}}

      - name: Add cherry-pick reminder
        env:
          GITHUB_TOKEN: ${{steps.get_workflow_token.outputs.token}}
          GH_TOKEN: ${{steps.get_workflow_token.outputs.token}}
          CHERRY_PICK_REMINDER: ${{vars.CHERRY_PICK_REMINDER}}
          BRANCHES_OUTPUT: ${{toJSON(steps.getbranches.outputs)}}
          BRANCH_COUNT: ${{steps.getbranches.outputs.branch_count}}
          FORCED_NONE:  ${{steps.getbranches.outputs.forced_none}}
        run: |
          # If the user already added "cherry-pick-to" comments
          # we don't need to remind them.
          ( $FORCED_NONE || [ $BRANCH_COUNT -gt 0 ] ) && { echo "No reminder needed." ; exit 0 ; }
          IFS=$'; \n'
          # If there's already a reminder comment, don't add another one.
          ADD_COMMENT=true
          # This query will FAIL if it finds the comment.
          gh pr view --repo ${{github.repository}} --json comments \
            --jq '.comments[].body | select(. | startswith("<!--CPR-->")) | halt_error(1)' \
            ${{env.PR_NUMBER}} >/dev/null 2>&1 || ADD_COMMENT=false
          if $ADD_COMMENT ; then
            echo "Adding CPR comment"
            gh pr comment --repo ${{github.repository}} \
              -b "${CHERRY_PICK_REMINDER}" ${{env.PR_NUMBER}}
          else
            echo "CPR comment already present"
          fi

      - name: Add reviewers
        if: github.event.action == 'opened'
        env:
          GITHUB_TOKEN: ${{steps.get_workflow_token.outputs.token}}
          GH_TOKEN: ${{steps.get_workflow_token.outputs.token}}
          CHERRY_PICK_REMINDER: ${{vars.CHERRY_PICK_REMINDER}}
          REVIEWERS: ${{vars.PR_REVIEWERS}}
        run: |
          IFS=$'; \n'
          for r in $REVIEWERS ; do
            echo "Adding reviewer $r"
            gh pr edit --repo ${{github.repository}} ${PR_NUMBER} --add-reviewer $r || :
          done

      - name: Set Labels
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit --repo ${{github.repository}} \
            --remove-label ${{vars.TEST_CHECKS_PASSED_LABEL}} \
            --remove-label ${{vars.TEST_CHECKS_FAILED_LABEL}} \
            --remove-label ${{vars.TEST_GATES_PASSED_LABEL}} \
            --remove-label ${{vars.TEST_GATES_FAILED_LABEL}} \
            --remove-label ${{vars.CHERRY_PICK_CHECKS_PASSED_LABEL}} \
            --remove-label ${{vars.CHERRY_PICK_CHECKS_FAILED_LABEL}} \
            --remove-label ${{vars.CHERRY_PICK_GATES_PASSED_LABEL}} \
            --remove-label ${{vars.CHERRY_PICK_GATES_FAILED_LABEL}} \
            --add-label ${{vars.TESTING_IN_PROGRESS}} \
            ${{env.PR_NUMBER}} || :

      - name: Run Unit Tests
        uses: asterisk/asterisk-ci-actions/AsteriskUnitComposite@main
        with:
          asterisk_repo:     ${{env.ASTERISK_REPO}}
          pr_number:         ${{env.PR_NUMBER}}
          base_branch:       ${{env.BRANCH}}
          modules_blacklist: ${{env.MODULES_BLACKLIST}}
          github_token:      ${{secrets.GITHUB_TOKEN}}
          unittest_command:  ${{vars.UNITTEST_COMMAND}}

      - name: Add Checks Passed Label
        if: ${{ success() }}
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit --repo ${{github.repository}} \
            --add-label ${{vars.TEST_CHECKS_PASSED_LABEL}} \
            ${{env.PR_NUMBER}} || :

  PROpenUpdateGateTestMatrix:
    needs: PROpenUpdateUnitTests
    continue-on-error: false
    strategy:
      fail-fast: false
      matrix:
        group: ${{ fromJSON(vars.GATETEST_LIST) }}
    runs-on: ubuntu-latest
    steps:
      - id: runtest
        name: Run Gate Tests for ${{ matrix.group }}
        uses: asterisk/asterisk-ci-actions/AsteriskGateComposite@main
        with:
          test_type:         Gate
          asterisk_repo:     ${{env.ASTERISK_REPO}}
          pr_number:         ${{env.PR_NUMBER}}
          base_branch:       ${{env.BRANCH}}
          modules_blacklist: ${{env.MODULES_BLACKLIST}}
          github_token:      ${{secrets.GITHUB_TOKEN}}
          testsuite_repo:    ${{vars.TESTSUITE_REPO}}
          gatetest_group:    ${{matrix.group}}
          gatetest_commands: ${{vars.GATETEST_COMMANDS}}


  PROpenUpdateGateTests:
    if: always()
    runs-on: ubuntu-latest
    needs: PROpenUpdateGateTestMatrix
    steps:
      - name: Check test matrix status
        env:
          RESULT: ${{ needs.PROpenUpdateGateTestMatrix.result }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "all results: ${{ toJSON(needs.*.result) }}"
          echo "composite result: $RESULT"

          gh pr edit --repo ${{github.repository}} \
            --remove-label ${{vars.TESTING_IN_PROGRESS}} \
            ${{env.PR_NUMBER}} || :

          case $RESULT in
            success)
              gh pr edit --repo ${{github.repository}} \
                --add-label ${{vars.TEST_GATES_PASSED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              echo "::notice::All Testsuite tests passed"
              exit 0
              ;;
            skipped)
              gh pr edit --repo ${{github.repository}} \
                --add-label ${{vars.TEST_CHECKS_FAILED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              echo "::error::Testsuite tests were skipped because of an earlier failure"
              exit 1
              ;;
            *)
              gh pr edit --repo ${{github.repository}} \
                --add-label ${{vars.TEST_GATES_FAILED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              echo "::error::One or more Testsuite tests failed ($RESULT)"
              exit 1
          esac
