name: Validate Main Green CI

on:
  workflow_dispatch:
    inputs:
      branch:
        description: "Branch to validate"
        required: false
        default: main
        type: string
      required_contexts:
        description: "Comma-separated required checks; use | for alternatives (e.g. ci-ok|ci-main / ci-ok)"
        required: false
        default: ci-ok|ci-main / ci-ok
        type: string
  workflow_call:
    inputs:
      branch:
        required: false
        default: main
        type: string
      required_contexts:
        required: false
        default: ci-ok|ci-main / ci-ok
        type: string

jobs:
  validate:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      checks: read
    steps:
      - name: validate required checks
        uses: actions/github-script@v9
        env:
          TARGET_BRANCH: ${{ inputs.branch || github.event.inputs.branch || 'main' }}
          REQUIRED_CONTEXTS: ${{ inputs.required_contexts || github.event.inputs.required_contexts || 'ci-ok|ci-main / ci-ok' }}
        with:
          script: |
            const owner = context.repo.owner;
            const repo = context.repo.repo;
            const branch = process.env.TARGET_BRANCH || "main";
            const groups = String(process.env.REQUIRED_CONTEXTS || "")
              .split(",")
              .map((s) => s.trim())
              .filter(Boolean)
              .map((group) =>
                group
                  .split("|")
                  .map((s) => s.trim())
                  .filter(Boolean)
              );

            const runId = String(context.runId);
            const branchResp = await github.rest.repos.getBranch({ owner, repo, branch });
            const sha = branchResp.data.commit.sha;
            core.info(`Validating checks for ${branch} @ ${sha}`);

            const checksAll = await github.paginate(github.rest.checks.listForRef, {
              owner,
              repo,
              ref: sha,
              per_page: 100,
            });
            const checks = checksAll.filter((c) => !(c.details_url || "").includes(`/actions/runs/${runId}/`));

            const newestByName = new Map();
            for (const c of checks) {
              const key = c.name;
              const prev = newestByName.get(key);
              if (!prev) {
                newestByName.set(key, c);
                continue;
              }
              const prevTime = Date.parse(prev.started_at || prev.completed_at || "") || 0;
              const curTime = Date.parse(c.started_at || c.completed_at || "") || 0;
              if (curTime >= prevTime) {
                newestByName.set(key, c);
              }
            }

            const failures = [];
            for (const alternatives of groups) {
              let ok = false;
              const altNotes = [];
              for (const name of alternatives) {
                const latest = newestByName.get(name);
                if (!latest) {
                  altNotes.push(`${name}: missing`);
                  continue;
                }
                if (latest.status !== "completed") {
                  altNotes.push(`${name}: status=${latest.status}, conclusion=${latest.conclusion}`);
                  continue;
                }
                if (["success", "neutral", "skipped"].includes(latest.conclusion || "")) {
                  ok = true;
                  break;
                }
                altNotes.push(`${name}: conclusion=${latest.conclusion}`);
              }
              if (!ok) {
                failures.push(`(${alternatives.join(" | ")}): none green — ${altNotes.join("; ")}`);
              }
            }

            if (failures.length > 0) {
              core.setFailed(`Required checks for ${branch} are not green:\n${failures.join("\n")}`);
              return;
            }

            const summary = groups
              .map((alts) => (alts.length > 1 ? `(${alts.join(" | ")})` : alts[0]))
              .join(", ");
            core.info(`All required checks for ${branch} are green (${summary}).`);
