name: Aider Auto-fix issues and PR comments via external prompt

on:
  issue_comment:
    types: [created]

jobs:
  check-membership:
    runs-on: ubicloud-standard-2
    if: |
      github.event_name == 'issue_comment' &&
      contains(github.event.comment.body, '/aider') &&
      !contains(github.event.comment.user.login, '[bot]')
    outputs:
      is_member: ${{ steps.check-membership.outputs.is_member }}
    steps:
      - name: Check organization membership
        id: check-membership
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          COMMENTER: ${{ github.event.comment.user.login }}
          ORG_ACCESS_TOKEN: ${{ secrets.ORG_ACCESS_TOKEN }}
        run: |
          ORG="windmill-labs"
          STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
            -H "Authorization: token $ORG_ACCESS_TOKEN" \
            -H "Accept: application/vnd.github+json" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            "https://api.github.com/orgs/$ORG/members/$COMMENTER")

          if [ "$STATUS" -eq 204 ]; then
            echo "is_member=true" >> $GITHUB_OUTPUT
          else
            echo "is_member=false" >> $GITHUB_OUTPUT
          fi

  check-and-prepare:
    needs: check-membership
    runs-on: ubicloud-standard-2
    if: needs.check-membership.outputs.is_member == 'true'
    permissions:
      contents: write
      pull-requests: write
      issues: write
    env:
      GEMINI_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
      GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      WINDMILL_TOKEN: ${{ secrets.WINDMILL_TOKEN }}
    outputs:
      issue_title: ${{ steps.determine_inputs.outputs.ISSUE_TITLE }}
      issue_body: ${{ steps.determine_inputs.outputs.ISSUE_BODY }}
      comment_content: ${{ steps.determine_inputs.outputs.COMMENT_CONTENT }}
      pr_branch: ${{ steps.checkout_pr.outputs.PR_BRANCH }}

    steps:
      - name: Acknowledge Request
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_REPOSITORY: ${{ github.repository }}
        run: |
          echo "Commenting on issue/PR #${{ github.event.issue.number }} to acknowledge the /aider command."
          gh issue comment ${{ github.event.issue.number }} --body "🤖 Aider is starting to work on your request. I'll update you here once I have a PR ready. Please be patient, this might take a few minutes." --repo $GITHUB_REPOSITORY

      - name: Determine inputs for Aider
        id: determine_inputs
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          COMMENT_BODY: ${{ github.event.comment.body }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }}
        run: |
          echo "Determining inputs for Aider..."
          ISSUE_TITLE_VAL=""
          ISSUE_BODY_VAL=""

          if [[ ! -z "${{ github.event.issue.pull_request }}" ]]; then
            echo "This is a comment on a Pull Request"
            PR_NUMBER="$ISSUE_NUMBER"
            
            PR_BODY_JSON=$(gh pr view "$PR_NUMBER" --json body --repo "$GITHUB_REPOSITORY")
            if [[ $? -ne 0 ]]; then
              echo "Error fetching PR body for PR #$PR_NUMBER"
              PR_BODY_VAL=""
            else
              PR_BODY_VAL=$(jq -r '.body // ""' <<< "$PR_BODY_JSON")
            fi
            
            if [[ ! -z "$PR_BODY_VAL" ]]; then
              REFERENCED_ISSUE=""
              if [[ "$PR_BODY_VAL" =~ \#linear:([a-f0-9-]+) ]]; then
                REFERENCED_ISSUE="${BASH_REMATCH[1]}"
                echo "Found referenced Linear issue #$REFERENCED_ISSUE in PR description"
                LINEAR_ISSUE_JSON=$(curl -s -H "Authorization: $LINEAR_API_KEY" \
                  "https://api.linear.app/graphql" \
                  -X POST \
                  -H "Content-Type: application/json" \
                  -d "{\"query\":\"query { issue(id: \\\"$REFERENCED_ISSUE\\\") { title description } }\"}")
                
                if [[ $? -eq 0 && ! "$LINEAR_ISSUE_JSON" =~ "error" ]]; then
                  ISSUE_TITLE_VAL=$(jq -r '.data.issue.title // ""' <<< "$LINEAR_ISSUE_JSON")
                  ISSUE_BODY_VAL=$(jq -r '.data.issue.description // ""' <<< "$LINEAR_ISSUE_JSON")
                  echo "Successfully fetched Linear issue details"
                else
                  echo "Error fetching Linear issue details for #$REFERENCED_ISSUE"
                fi
              elif [[ "$PR_BODY_VAL" =~ \#([0-9]+) ]]; then
                REFERENCED_ISSUE="${BASH_REMATCH[1]}"
                echo "Found referenced GitHub issue #$REFERENCED_ISSUE in PR description"
                
                ISSUE_DETAILS_JSON=$(gh issue view "$REFERENCED_ISSUE" --json title,body --repo "$GITHUB_REPOSITORY")
                if [[ $? -ne 0 ]]; then
                  echo "Error fetching issue details for #$REFERENCED_ISSUE"
                else
                  ISSUE_TITLE_VAL=$(jq -r '.title // ""' <<< "$ISSUE_DETAILS_JSON")
                  ISSUE_BODY_VAL=$(jq -r '.body // ""' <<< "$ISSUE_DETAILS_JSON")
                fi
              fi
            else
              echo "PR body is empty or could not be fetched."
            fi
          else
            echo "This is a comment on a regular issue"
            
            ISSUE_DETAILS_JSON=$(gh issue view "$ISSUE_NUMBER" --json title,body --repo "$GITHUB_REPOSITORY")
            if [[ $? -ne 0 ]]; then
              echo "Error fetching issue details for #$ISSUE_NUMBER"
            else
              ISSUE_TITLE_VAL=$(jq -r '.title // ""' <<< "$ISSUE_DETAILS_JSON")
              ISSUE_BODY_VAL=$(jq -r '.body // ""' <<< "$ISSUE_DETAILS_JSON") 
            fi
          fi

          echo "ISSUE_TITLE<<EOF_AIDER_TITLE" >> "$GITHUB_OUTPUT"
          echo "$ISSUE_TITLE_VAL" >> "$GITHUB_OUTPUT"
          echo "EOF_AIDER_TITLE" >> "$GITHUB_OUTPUT"

          echo "ISSUE_BODY<<EOF_AIDER_BODY" >> "$GITHUB_OUTPUT"
          echo "$ISSUE_BODY_VAL" >> "$GITHUB_OUTPUT"
          echo "EOF_AIDER_BODY" >> "$GITHUB_OUTPUT"

          CLEAN_COMMENT="${COMMENT_BODY/\/aider/}"
          CLEAN_COMMENT="${CLEAN_COMMENT#"${CLEAN_COMMENT%%[![:space:]]*}"}"
          CLEAN_COMMENT="${CLEAN_COMMENT%"${CLEAN_COMMENT##*[![:space:]]}"}"

          echo "COMMENT_CONTENT<<EOF_AIDER_COMMENT" >> "$GITHUB_OUTPUT"
          echo "$CLEAN_COMMENT" >> "$GITHUB_OUTPUT"
          echo "EOF_AIDER_COMMENT" >> "$GITHUB_OUTPUT"
          echo "Finished determining inputs."

  run-aider:
    needs: [check-membership, check-and-prepare]
    if: needs.check-membership.outputs.is_member == 'true'
    uses: ./.github/workflows/aider-common.yml
    with:
      issue_title: ${{ needs.check-and-prepare.outputs.issue_title }}
      issue_body: ${{ needs.check-and-prepare.outputs.issue_body }}
      instruction: ${{ needs.check-and-prepare.outputs.comment_content }}
      issue_id: ${{ github.event.issue.number }}
      rules_files: ".cursor/rules/rust-best-practices.mdc .cursor/rules/svelte5-best-practices.mdc .cursor/rules/windmill-overview.mdc"
    secrets: inherit
