name: Build LMS Scheduler
on:
  workflow_dispatch:
  schedule:
    - cron:  '40 2,3,4 * * *'

jobs:
  check:
    name: Check whether build is needed
    if: ${{ github.repository_owner == 'LMS-Community' || github.event_name == 'workflow_dispatch' }}
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            const repoStatus = await github.request('GET https://raw.githubusercontent.com/LMS-Community/lms-server-repository/refs/heads/master/servers.json');

            if (repoStatus.status !== 200) {
              console.error("Fetching repo file failed?" + JSON.stringify(repoStatus, null, 2));
              return false;
            }

            // get the oldest timestamp for each version from previous builds
            const candidates = [];
            const repoData = JSON.parse(repoStatus.data);

            Object.keys(repoData).sort((a, b) => {
              return 0.5 - Math.random();
            }).forEach(version => {
              const matches = version.match(/(\d+\.\d+)\.\d+/);
              if (matches && matches.length == 2) {
                const versionBuilds = repoData[version];
                candidates.push({
                  v: matches[1],
                  r: Object.keys(versionBuilds).reduce((accumulator, build) => {
                    const buildInfo = versionBuilds[build];
                    accumulator = accumulator || parseInt(buildInfo.revision);
                    return Math.min(accumulator, parseInt(buildInfo.revision));
                  }, 0)
                })
              }
              else {
                delete repoData[version];
              }
            });

            // for each version see whether there's a more recent commit than the revision of the previous build
            for (let i = 0; i < candidates.length; i++) {
              const latestBuildTimestamp = candidates[i].r * 1000;

              const commitStatus = await github.rest.repos.listCommits({
                owner: context.repo.owner,
                repo: context.repo.repo,
                sha: 'public/' + candidates[i].v,
                per_page: 1,
                sort: 'created',
                order: 'asc',
              });

              if (commitStatus.status !== 200) {
                console.log(JSON.stringify(commitStatus, null, 2));
                continue;
              }

              // see whether there's really been a commit since that timestamp - above "since" would be inclusive
              const needsBuild = commitStatus.data.find(commit => new Date(commit.commit.committer.date).getTime() > latestBuildTimestamp);

              if (needsBuild) {
                console.log(`${candidates[i].v}: needs a build (${new Date(needsBuild.commit.committer.date).getTime()} > ${latestBuildTimestamp})`);

                const workflowStatus = await github.rest.actions.createWorkflowDispatch({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  workflow_id: '00_build.yaml',
                  ref: 'public/' + candidates[i].v,
                  inputs: {
                    branch: 'public/' + candidates[i].v,
                    build_type: 'nightly',
                  },
                });

                if (workflowStatus.status < 200 || workflowStatus.status > 204) {
                  console.log(workflowStatus);
                }

                // we only want to run one build at a time - we'll re run the check in a bit
                break;
              }
              else {
                console.log(`${candidates[i].v}: is up to date (${candidates[i].r})`);
              }
            }
