# Responds to `/gitnexus index` comments on pull requests.
#
# Gated to the same author_association roles (OWNER, MEMBER, COLLABORATOR)
# as the automatic PR index trigger, but applied to the COMMENTER, not
# the PR author. This intentionally lets a contributor index a PR from
# a non-contributor / first-time fork author — the contributor takes
# responsibility for the trust boundary by typing the command.
#
# When a matching comment lands on a PR, this workflow dispatches
# `gitnexus-index.yml` with the PR number and the `refs/pull/<N>/head`
# ref so indexing works for fork PRs too (GitHub mirrors every PR's
# head ref into the base repo regardless of which fork it originated
# from, so actions/checkout can always resolve it).
#
# Use cases:
#   - Re-index a PR after a rebase without pushing a new commit
#   - Index a docs-only PR that was skipped by paths-ignore
#   - Index a non-contributor (fork) PR that the auto-trigger skipped
#   - Re-run a failed index
#
# Supported commands:
#   /gitnexus index             — index the PR with embeddings (default)
#   /gitnexus index embeddings  — explicit form of the above; same effect
#   /gitnexus index fast        — graph-only index (skip embeddings), for
#                                 a quick re-index without waiting ~5 min
#                                 of embedding generation

name: GitNexus PR Command

on:
  issue_comment:
    types: [created]

permissions:
  contents: read
  pull-requests: write
  actions: write # needed to dispatch gitnexus-index.yml

concurrency:
  group: gitnexus-pr-command-${{ github.event.issue.number }}
  cancel-in-progress: false

jobs:
  dispatch:
    # Only run for PR comments that start with /gitnexus from trusted
    # commenters. Intentionally checks the COMMENTER's association so a
    # contributor can index a non-contributor's PR on demand.
    if: |
      github.event.issue.pull_request != null &&
      startsWith(github.event.comment.body, '/gitnexus') &&
      (github.event.comment.author_association == 'OWNER' ||
       github.event.comment.author_association == 'MEMBER' ||
       github.event.comment.author_association == 'COLLABORATOR')
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: Parse command and resolve PR head ref
        id: parse
        uses: actions/github-script@v7
        with:
          script: |
            const body = context.payload.comment.body.trim();
            const match = body.match(/^\/gitnexus\s+(\w+)(?:\s+(\w+))?/);
            if (!match) {
              core.setFailed(`Unrecognized command: ${body}. Try: /gitnexus index [fast]`);
              return;
            }
            const [, subcommand, modifier] = match;
            if (subcommand !== 'index') {
              core.setFailed(`Unknown subcommand: ${subcommand}. Only 'index' is supported.`);
              return;
            }
            // Default to embeddings on — a contributor typing the command
            // has already decided they want a full re-index. The `fast`
            // modifier is the explicit opt-out for graph-only runs.
            // `embeddings` is accepted as a no-op alias for backwards
            // compat with the previous command form.
            let embeddings = 'true';
            if (modifier === 'fast' || modifier === 'graph-only' || modifier === 'no-embeddings') {
              embeddings = 'false';
            }

            // Use refs/pull/<N>/head instead of the raw head SHA. GitHub
            // mirrors every PR's head into the base repo as this ref, so
            // actions/checkout can always resolve it — even for PRs from
            // forks whose raw SHAs don't exist in the base repo.
            const prNum = context.payload.issue.number;
            core.setOutput('pr_number', String(prNum));
            core.setOutput('pr_ref', `refs/pull/${prNum}/head`);
            core.setOutput('embeddings', embeddings);
            core.info(
              `Dispatching index for PR #${prNum} at refs/pull/${prNum}/head (embeddings=${embeddings}, modifier=${modifier || '(none)'})`,
            );

      - name: Dispatch gitnexus-index workflow
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.actions.createWorkflowDispatch({
              owner: context.repo.owner,
              repo: context.repo.repo,
              workflow_id: 'gitnexus-index.yml',
              ref: 'main',
              inputs: {
                pr_number: '${{ steps.parse.outputs.pr_number }}',
                pr_ref: '${{ steps.parse.outputs.pr_ref }}',
                embeddings: '${{ steps.parse.outputs.embeddings }}',
                force: 'false',
              },
            });

      - name: React to the comment
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.reactions.createForIssueComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              comment_id: context.payload.comment.id,
              content: 'rocket',
            });
