name: Auto Label Issues by Package

on:
  issues:
    types: [opened, edited]

permissions:
  contents: read

jobs:
  label-by-package:
    permissions:
      issues: write
    runs-on: ubuntu-latest

    steps:
      - name: Sync package labels
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        with:
          script: |
            const body = context.payload.issue.body || "";

            // Extract text under "## Package" or "### Package" (handles " (Required)" suffix and being last section)
            const match = body.match(/#{2,3} Package[^\n]*\n([\s\S]*?)(?:\n#{2,3} |$)/i);
            if (!match) {
              core.setFailed(
                `Could not find "## Package" section in issue #${context.issue.number} body. ` +
                `The issue template may have changed — update the regex in this workflow.`
              );
              return;
            }

            const packageSection = match[1].trim();

            // Mapping table for package names to labels
            const mapping = {
              "langchain": "langchain",
              "langchain-openai": "openai",
              "langchain-anthropic": "anthropic",
              "langchain-classic": "langchain-classic",
              "langchain-core": "core",
              "langchain-model-profiles": "model-profiles",
              "langchain-tests": "standard-tests",
              "langchain-text-splitters": "text-splitters",
              "langchain-chroma": "chroma",
              "langchain-deepseek": "deepseek",
              "langchain-exa": "exa",
              "langchain-fireworks": "fireworks",
              "langchain-groq": "groq",
              "langchain-huggingface": "huggingface",
              "langchain-mistralai": "mistralai",
              "langchain-nomic": "nomic",
              "langchain-ollama": "ollama",
              "langchain-openrouter": "openrouter",
              "langchain-perplexity": "perplexity",
              "langchain-qdrant": "qdrant",
              "langchain-xai": "xai",
            };

            // All possible package labels we manage
            const allPackageLabels = Object.values(mapping);
            const selectedLabels = [];

            // Check if this is checkbox format (multiple selection)
            const checkboxMatches = packageSection.match(/- \[x\]\s+([^\n\r]+)/gi);
            if (checkboxMatches) {
              // Handle checkbox format
              for (const match of checkboxMatches) {
                const packageName = match.replace(/- \[x\]\s+/i, '').trim();
                const label = mapping[packageName];
                if (label && !selectedLabels.includes(label)) {
                  selectedLabels.push(label);
                }
              }
            } else {
              // Handle dropdown format (single selection)
              const label = mapping[packageSection];
              if (label) {
                selectedLabels.push(label);
              }
            }

            // Get current issue labels
            const issue = await github.rest.issues.get({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number
            });

            const currentLabels = issue.data.labels.map(label => label.name);
            const currentPackageLabels = currentLabels.filter(label => allPackageLabels.includes(label));

            // Determine labels to add and remove
            const labelsToAdd = selectedLabels.filter(label => !currentPackageLabels.includes(label));
            const labelsToRemove = currentPackageLabels.filter(label => !selectedLabels.includes(label));

            // Add new labels
            if (labelsToAdd.length > 0) {
              await github.rest.issues.addLabels({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                labels: labelsToAdd
              });
            }

            // Remove old labels
            for (const label of labelsToRemove) {
              await github.rest.issues.removeLabel({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                name: label
              });
            }
