import { Octokit } from "@octokit/rest";
import { throttling } from "@octokit/plugin-throttling";
import { retry } from "@octokit/plugin-retry";
Octokit.plugin(throttling);
Octokit.plugin(retry);
const octokit = new Octokit({
  auth: process.env.GITHUB_TOKEN,
  userAgent: 'PCSX2/pcsx2',
  log: {
    debug: () => { },
    info: () => { },
    warn: console.warn,
    error: console.error
  },
  throttle: {
    onRateLimit: (retryAfter, options) => {
      octokit.log.warn(
        `Request quota exhausted for request ${options.method} ${options.url}`
      );

      // Retry twice after hitting a rate limit error, then give up
      if (options.request.retryCount <= 2) {
        console.log(`Retrying after ${retryAfter} seconds!`);
        return true;
      }
    },
    onAbuseLimit: (retryAfter, options) => {
      // does not retry, only logs a warning
      octokit.log.warn(
        `Abuse detected for request ${options.method} ${options.url}`
      );
    },
  }
});

let assetDir = process.env.ASSET_DIR;
let tagToSearchFor = process.env.TAG_TO_SEARCH_FOR.split("refs/tags/")[1];

console.log(`Searching in - ${assetDir}`);
console.log(`Searching for tag - ${tagToSearchFor}`);

const { data: recentReleases } = await octokit.rest.repos.listReleases({
  owner: "PCSX2",
  repo: "pcsx2",
  per_page: 100
});

let release = undefined;
for (var i = 0; i < recentReleases.length; i++) {
  if (recentReleases[i].tag_name == tagToSearchFor) {
    release = recentReleases[i];
    break;
  }
}

if (release == undefined) {
  console.log(`Unable to find release with tag - ${tagToSearchFor}`);
  process.exit(1);
}

// Upload any assets we need to, don't upload assets that are already there!
const { data: releaseAssetsPre } = await octokit.rest.repos.listReleaseAssets({
  owner: "PCSX2",
  repo: "pcsx2",
  release_id: release.id,
  per_page: 100
});

import glob from 'glob';
import * as fs from 'fs';
import * as path from 'path';
glob(assetDir + `/**/*${process.env.ASSET_EXTENSION}`, {}, async (err, files) => {
  for (var i = 0; i < files.length; i++) {
    let foundDuplicate = false;
    for (var j = 0; j < releaseAssetsPre.length; j++) {
      let existingAsset = releaseAssetsPre[j];
      if (existingAsset.name == `pcsx2-${release.tag_name}-${path.basename(files[i])}`) {
        foundDuplicate = true;
        break;
      }
    }
    if (foundDuplicate) {
      continue;
    }

    var assetBytes = fs.readFileSync(files[i], null);
    const { data: uploadAsset } = await octokit.rest.repos.uploadReleaseAsset({
      owner: "PCSX2",
      repo: "pcsx2",
      release_id: release.id,
      name: `pcsx2-${release.tag_name}-${path.basename(files[i])}`,
      data: assetBytes,
    });
  }
});

// Ideally there would be a webhook event for when an artifact is added to a draft release
// unfortunately, such a thing does not exist yet.  Therefore, we have to wait a bit
// for the API to become consistent
// TODO - future work - we could check previous draft releases to become eventually consistent as well
// - draft releases should only be a temporary state, so anything that remains a draft had a problem
await new Promise(resolve => setTimeout(resolve, 10 * 1000));

// Poll the release, and check to see if it's ready to be published
const { data: releaseAssetsPost } = await octokit.rest.repos.listReleaseAssets({
  owner: "PCSX2",
  repo: "pcsx2",
  release_id: release.id,
  per_page: 100
});

// Expected Assets, if we have all of them, we will publish it
let expectedAssets = {
  "windows-64bit-sse4": false,
  "windows-64bit-avx2": false,
  "linux-appimage-64bit": false
}

for (var i = 0; i < releaseAssetsPost.length; i++) {
  let asset = releaseAssetsPost[i];
  if (asset.name.includes("symbols")) {
    continue;
  }
  for (var j = 0; j < Object.keys(expectedAssets).length; j++) {
    let expectedNamePrefix = Object.keys(expectedAssets)[j];
    if (asset.name.toLowerCase().includes(expectedNamePrefix)) {
      expectedAssets[expectedNamePrefix] = true;
      break;
    }
  }
}

console.log(expectedAssets);

if (Object.values(expectedAssets).every(Boolean)) {
  await octokit.rest.repos.updateRelease({
    owner: "PCSX2",
    repo: "pcsx2",
    release_id: release.id,
    draft: false
  });
}
