#!/usr/bin/env node --redirect-warnings=/dev/null

const { execFileSync } = require("child_process");
const { GITHUB_ACCESS_TOKEN } = process.env;

main();

async function main() {
  const startDate = new Date(process.argv[2]);
  const today = new Date();

  console.log(`Release notes from ${startDate} to ${today}\n`);

  const releases = await getReleases(startDate, today);
  const previewReleases = releases.filter((release) =>
    release.tagName.includes("-pre"),
  );

  const stableReleases = releases.filter(
    (release) => !release.tagName.includes("-pre"),
  );

  // Filter out all preview release, as all of those changes have made it to the stable release, except for the latest preview release
  const aggregatedReleases = stableReleases
    .concat(previewReleases[0])
    .reverse();

  const aggregatedReleaseTitles = aggregatedReleases
    .map((release) => release.name)
    .join(", ");

  console.log();
  console.log(`Release titles: ${aggregatedReleaseTitles}`);

  console.log("Release notes:");
  console.log();

  for (const release of aggregatedReleases) {
    const publishedDate = release.publishedAt.split("T")[0];
    console.log(`${release.name}: ${publishedDate}`);
    console.log();
    console.log(release.description);
    console.log();
  }
}

async function getReleases(startDate, endDate) {
  const query = `
    query ($owner: String!, $repo: String!, $cursor: String) {
      repository(owner: $owner, name: $repo) {
        releases(first: 100, orderBy: {field: CREATED_AT, direction: DESC}, after: $cursor) {
          nodes {
            tagName
            name
            createdAt
            publishedAt
            description
            url
            author {
              login
            }
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
    }
  `;

  let allReleases = [];
  let hasNextPage = true;
  let cursor = null;

  while (hasNextPage) {
    const response = await fetch("https://api.github.com/graphql", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${GITHUB_ACCESS_TOKEN}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        query,
        variables: { owner: "zed-industries", repo: "zed", cursor },
      }),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();

    if (data.errors) {
      throw new Error(`GraphQL error: ${JSON.stringify(data.errors)}`);
    }

    if (!data.data || !data.data.repository || !data.data.repository.releases) {
      throw new Error(`Unexpected response structure: ${JSON.stringify(data)}`);
    }

    const releases = data.data.repository.releases.nodes;
    allReleases = allReleases.concat(releases);

    hasNextPage = data.data.repository.releases.pageInfo.hasNextPage;
    cursor = data.data.repository.releases.pageInfo.endCursor;

    lastReleaseOnPage = releases[releases.length - 1];

    if (
      releases.length > 0 &&
      new Date(lastReleaseOnPage.createdAt) < startDate
    ) {
      break;
    }
  }

  const filteredReleases = allReleases.filter((release) => {
    const releaseDate = new Date(release.createdAt);
    return releaseDate >= startDate && releaseDate <= endDate;
  });

  return filteredReleases;
}
