name: vouch-check-issue

on:
  issues:
    types: [opened]

permissions:
  contents: read
  issues: write

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - name: Check if issue author is denounced
        uses: actions/github-script@v7
        with:
          script: |
            const author = context.payload.issue.user.login;
            const issueNumber = context.payload.issue.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 issue
              const body = 'This issue has been automatically closed.';

              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: issueNumber,
                body,
              });

              await github.rest.issues.update({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: issueNumber,
                state: 'closed',
                state_reason: 'not_planned',
              });

              core.info(`Closed issue #${issueNumber} 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 issue.`);
              return;
            }

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

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