# Adapted from https://github.com/huggingface/diffusers/blob/main/.github/workflows/pr_style_bot.yml
name: PR Style Bot

on:
  issue_comment:
    types: [created]

permissions: {}

env:
  PYTHON_VERSION: "3.10"

jobs:
  check-permissions:
    if: >
      contains(github.event.comment.body, '@bot /style') &&
      github.event.issue.pull_request != null
    runs-on: ubuntu-latest
    outputs:
      is_authorized: ${{ steps.check_user_permission.outputs.has_permission }}
    steps:
      - name: Check user permission
        id: check_user_permission
        uses: actions/github-script@v6
        with:
          script: |
            const comment_user = context.payload.comment.user.login;
            const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
              owner: context.repo.owner,
              repo: context.repo.repo,
              username: comment_user
            });

            const authorized =
              permission.permission === 'admin' ||
              permission.permission === 'write';

            console.log(
              `User ${comment_user} has permission level: ${permission.permission}, ` +
              `authorized: ${authorized} (admins & maintainers allowed)`
            );

            core.setOutput('has_permission', authorized);

  run-style-bot:
    needs: check-permissions
    if: needs.check-permissions.outputs.is_authorized == 'true'
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Extract PR details
        id: pr_info
        uses: actions/github-script@v6
        with:
          script: |
            const prNumber = context.payload.issue.number;
            const { data: pr } = await github.rest.pulls.get({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: prNumber
            });

            // We capture both the branch ref and the "full_name" of the head repo
            // so that we can check out the correct repository & branch (including forks).
            core.setOutput("prNumber", prNumber);
            core.setOutput("headRef", pr.head.ref);
            core.setOutput("headRepoFullName", pr.head.repo.full_name);

      - name: Check out PR branch
        uses: actions/checkout@v4
        env:
          HEADREPOFULLNAME: ${{ steps.pr_info.outputs.headRepoFullName }}
          HEADREF: ${{ steps.pr_info.outputs.headRef }}
        with:
          persist-credentials: true
          # Instead of checking out the base repo, use the contributor's repo name
          repository: ${{ env.HEADREPOFULLNAME }}
          ref: ${{ env.HEADREF }}
          # You may need fetch-depth: 0 for being able to push
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Debug
        env:
          HEADREPOFULLNAME: ${{ steps.pr_info.outputs.headRepoFullName }}
          HEADREF: ${{ steps.pr_info.outputs.headRef }}
          PRNUMBER: ${{ steps.pr_info.outputs.prNumber }}
        run: |
          echo "PR number: ${PRNUMBER}"
          echo "Head Ref: ${HEADREF}"
          echo "Head Repo Full Name: ${HEADREPOFULLNAME}"

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Get Ruff Version from pre-commit-config.yaml
        id: get-ruff-version
        run: |
          RUFF_VERSION=$(awk '/repo: https:\/\/github.com\/astral-sh\/ruff-pre-commit/{flag=1;next}/rev:/{if(flag){print $2;exit}}' .pre-commit-config.yaml)
          echo "ruff_version=${RUFF_VERSION}" >> $GITHUB_OUTPUT

      - name: Install Ruff
        env:
          RUFF_VERSION: ${{ steps.get-ruff-version.outputs.ruff_version }}
        run: python -m pip install "ruff==${RUFF_VERSION}"

      - name: Ruff check
        run: ruff check --fix

      - name: Ruff format
        run: ruff format

      - name: Commit and push changes
        id: commit_and_push
        env:
          HEADREPOFULLNAME: ${{ steps.pr_info.outputs.headRepoFullName }}
          HEADREF: ${{ steps.pr_info.outputs.headRef }}
          PRNUMBER: ${{ steps.pr_info.outputs.prNumber }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "HEADREPOFULLNAME: ${HEADREPOFULLNAME}, HEADREF: ${HEADREF}"
          # Configure git with the Actions bot user
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git config --local lfs.https://github.com/.locksverify false

          # Make sure your 'origin' remote is set to the contributor's fork
          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${HEADREPOFULLNAME}.git"

          # If there are changes after running style/quality, commit them
          if [ -n "$(git status --porcelain)" ]; then
            git add .
            git commit -m "Apply style fixes"
            # Push to the original contributor's forked branch
            git push origin HEAD:${HEADREF}
            echo "changes_pushed=true" >> $GITHUB_OUTPUT
          else
            echo "No changes to commit."
            echo "changes_pushed=false" >> $GITHUB_OUTPUT
          fi

      - name: Comment on PR with workflow run link
        if: steps.commit_and_push.outputs.changes_pushed == 'true'
        uses: actions/github-script@v6
        with:
          script: |
            const prNumber = parseInt(process.env.prNumber, 10);
            const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`

            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
              body: `Style fixes have been applied. [View the workflow run here](${runUrl}).`
            });
        env:
          prNumber: ${{ steps.pr_info.outputs.prNumber }}
