name: vouch-check-pr

on:
  pull_request_target:
    types: [opened]

permissions:
  contents: read
  issues: write
  pull-requests: write

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - name: Check if PR author is denounced
        uses: actions/github-script@v7
        with:
          script: |
            const author = context.payload.pull_request.user.login;
            const prNumber = context.payload.pull_request.number;

            // Skip bots
            if (author.endsWith('[bot]')) {
              core.info(`Skipping bot: ${author}`);
              return;
            }

            // Read the VOUCHED.td file via API (no checkout needed)
            let content;
            try {
              const response = await github.rest.repos.getContent({
                owner: context.repo.owner,
                repo: context.repo.repo,
                path: '.github/VOUCHED.td',
              });
              content = Buffer.from(response.data.content, 'base64').toString('utf-8');
            } catch (error) {
              if (error.status === 404) {
                core.info('No .github/VOUCHED.td file found, skipping check.');
                return;
              }
              throw error;
            }

            // Parse the .td file for vouched and denounced users
            const vouched = new Set();
            const denounced = new Map();
            for (const line of content.split('\n')) {
              const trimmed = line.trim();
              if (!trimmed || trimmed.startsWith('#')) continue;

              const isDenounced = trimmed.startsWith('-');
              const rest = isDenounced ? trimmed.slice(1).trim() : trimmed;
              if (!rest) continue;

              const spaceIdx = rest.indexOf(' ');
              const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx);
              const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim();

              // Handle platform:username or bare username
              // Only match bare usernames or github: prefix (skip other platforms)
              const colonIdx = handle.indexOf(':');
              if (colonIdx !== -1) {
                const platform = handle.slice(0, colonIdx).toLowerCase();
                if (platform !== 'github') continue;
              }
              const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1);
              if (!username) continue;

              if (isDenounced) {
                denounced.set(username.toLowerCase(), reason);
                continue;
              }

              vouched.add(username.toLowerCase());
            }

            // Check if the author is denounced
            const reason = denounced.get(author.toLowerCase());
            if (reason !== undefined) {
              // Author is denounced — close the PR
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: prNumber,
                body: 'This pull request has been automatically closed.',
              });

              await github.rest.pulls.update({
                owner: context.repo.owner,
                repo: context.repo.repo,
                pull_number: prNumber,
                state: 'closed',
              });

              core.info(`Closed PR #${prNumber} from denounced user ${author}`);
              return;
            }

            // Author is positively vouched — add label
            if (!vouched.has(author.toLowerCase())) {
              core.info(`User ${author} is not denounced or vouched. Allowing PR.`);
              return;
            }

            await github.rest.issues.addLabels({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
              labels: ['Vouched'],
            });

            core.info(`Added vouched label to PR #${prNumber} from ${author}`);
