name: PR Milestone Check

on:
  pull_request:
    types: [opened, reopened, edited, synchronize, milestoned, demilestoned]
    branches:
      - "main"
      - "release-v*.*.*"

jobs:
  check-milestone:
    name: Check PR Milestone
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Validate PR milestone
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            // Get PR number directly from the event payload
            const prNumber = context.payload.pull_request.number;

            // Get PR details
            const { data: prData } = await github.rest.pulls.get({
              owner: 'meilisearch',
              repo: 'meilisearch',
              pull_number: prNumber
            });

            // Get base branch name
            const baseBranch = prData.base.ref;
            console.log(`Base branch: ${baseBranch}`);

            // Get PR milestone
            const prMilestone = prData.milestone;
            if (!prMilestone) {
              core.setFailed('PR must have a milestone assigned');
              return;
            }
            console.log(`PR milestone: ${prMilestone.title}`);

            // Validate milestone format: vx.y.z
            const milestoneRegex = /^v\d+\.\d+\.\d+$/;
            if (!milestoneRegex.test(prMilestone.title)) {
              core.setFailed(`Milestone "${prMilestone.title}" does not follow the required format vx.y.z`);
              return;
            }

            // For main branch PRs, check if the milestone is the highest one
            if (baseBranch === 'main') {
              // Get all milestones
              const { data: milestones } = await github.rest.issues.listMilestones({
                owner: 'meilisearch',
                repo: 'meilisearch',
                state: 'open',
                sort: 'due_on',
                direction: 'desc'
              });

              // Sort milestones by version number (vx.y.z)
              const sortedMilestones = milestones
                .filter(m => milestoneRegex.test(m.title))
                .sort((a, b) => {
                  const versionA = a.title.substring(1).split('.').map(Number);
                  const versionB = b.title.substring(1).split('.').map(Number);

                  // Compare major version
                  if (versionA[0] !== versionB[0]) return versionB[0] - versionA[0];
                  // Compare minor version
                  if (versionA[1] !== versionB[1]) return versionB[1] - versionA[1];
                  // Compare patch version
                  return versionB[2] - versionA[2];
                });

              if (sortedMilestones.length === 0) {
                core.setFailed('No valid milestones found in the repository. Please create at least one milestone with the format vx.y.z');
                return;
              }

              const highestMilestone = sortedMilestones[0];
              console.log(`Highest milestone: ${highestMilestone.title}`);

              if (prMilestone.title !== highestMilestone.title) {
                core.setFailed(`PRs targeting the main branch must use the highest milestone (${highestMilestone.title}), but this PR uses ${prMilestone.title}`);
                return;
              }
            } else {
              // For release branches, the milestone should match the branch version
              const branchVersion = baseBranch.substring(8); // remove 'release-'
              if (prMilestone.title !== branchVersion) {
                core.setFailed(`PRs targeting release branch "${baseBranch}" must use the matching milestone "${branchVersion}", but this PR uses "${prMilestone.title}"`);
                return;
              }
            }

            console.log('PR milestone validation passed!');
