"use strict";
/* Socket Lib - Built with esbuild */
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var github_listing_exports = {};
__export(github_listing_exports, {
  fetchReleasesViaGraphQL: () => fetchReleasesViaGraphQL,
  fetchReleasesViaRest: () => fetchReleasesViaRest,
  getLatestRelease: () => getLatestRelease
});
module.exports = __toCommonJS(github_listing_exports);
var import_request = require("../http-request/request");
var import_retry = require("../promises/retry");
var import_array = require("../primordials/array");
var import_date = require("../primordials/date");
var import_error = require("../primordials/error");
var import_json = require("../primordials/json");
var import_object = require("../primordials/object");
var import_string = require("../primordials/string");
var import_github_assets = require("./github-assets");
var import_github_auth = require("./github-auth");
const RETRY_CONFIG = (0, import_object.ObjectFreeze)({
  __proto__: null,
  // Exponential backoff: delay doubles with each retry (5s, 10s, 20s).
  backoffFactor: 2,
  // Initial delay before first retry.
  baseDelayMs: 5e3,
  // Maximum number of retry attempts (excluding initial request).
  retries: 2
});
async function fetchReleasesViaGraphQL(owner, repo) {
  const response = await (0, import_request.httpRequest)("https://api.github.com/graphql", {
    body: (0, import_json.JSONStringify)({
      query: `query($owner: String!, $repo: String!) {
        repository(owner: $owner, name: $repo) {
          releases(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {
            nodes {
              tagName
              publishedAt
              releaseAssets(first: 100) { nodes { name } }
            }
          }
        }
      }`,
      variables: { owner, repo }
    }),
    headers: { ...(0, import_github_auth.getAuthHeaders)(), "Content-Type": "application/json" },
    method: "POST"
  });
  if (!response.ok) {
    throw new import_error.ErrorCtor(
      `Failed to fetch ${owner}/${repo} releases (GraphQL): ${response.status}`
    );
  }
  let parsed;
  try {
    parsed = (0, import_json.JSONParse)(response.body.toString("utf8"));
  } catch (cause) {
    throw new import_error.ErrorCtor(
      `Failed to parse GitHub GraphQL response for ${owner}/${repo} releases`,
      { cause }
    );
  }
  if (parsed.errors?.length) {
    throw new import_error.ErrorCtor(
      `GraphQL repository.releases(${owner}/${repo}) returned errors: ${parsed.errors.map((e) => e.message).join("; ")}`
    );
  }
  return (parsed.data?.repository?.releases?.nodes ?? []).map((n) => ({
    tag_name: n.tagName,
    published_at: n.publishedAt,
    assets: n.releaseAssets?.nodes ?? []
  }));
}
async function fetchReleasesViaRest(owner, repo) {
  const response = await (0, import_request.httpRequest)(
    `https://api.github.com/repos/${owner}/${repo}/releases?per_page=100`,
    { headers: (0, import_github_auth.getAuthHeaders)() }
  );
  if (!response.ok) {
    throw new import_error.ErrorCtor(
      `Failed to fetch ${owner}/${repo} releases: ${response.status}`
    );
  }
  const text = response.body.toString("utf8");
  if (text.length === 0) {
    return [];
  }
  let parsed;
  try {
    parsed = (0, import_json.JSONParse)(text);
  } catch (cause) {
    throw new import_error.ErrorCtor(`Failed to parse ${owner}/${repo} releases response`, {
      cause
    });
  }
  return (0, import_array.ArrayIsArray)(parsed) ? parsed : [];
}
async function getLatestRelease(toolPrefix, repoConfig, options = {}) {
  const { assetPattern, nothrow = false } = options;
  const { owner, repo } = repoConfig;
  const isMatch = assetPattern ? (0, import_github_assets.createAssetMatcher)(assetPattern) : void 0;
  return await (0, import_retry.pRetry)(async () => {
    let releases = await fetchReleasesViaRest(owner, repo);
    if (releases.length === 0) {
      let graphqlReleases;
      try {
        graphqlReleases = await fetchReleasesViaGraphQL(owner, repo);
      } catch (cause) {
        if (nothrow) {
          return void 0;
        }
        throw new import_error.ErrorCtor(
          `Failed to list ${owner}/${repo} releases: both REST and GraphQL backends degraded`,
          { cause }
        );
      }
      if (graphqlReleases.length > 0) {
        releases = graphqlReleases;
      }
    }
    const matchingReleases = releases.filter((release) => {
      const { assets, tag_name: tag } = release;
      if (!(0, import_string.StringPrototypeStartsWith)(tag, toolPrefix)) {
        return false;
      }
      if (!assets || assets.length === 0) {
        return false;
      }
      if (isMatch) {
        const hasMatchingAsset = assets.some(
          (a) => isMatch(a.name)
        );
        if (!hasMatchingAsset) {
          return false;
        }
      }
      return true;
    });
    if (matchingReleases.length === 0) {
      return void 0;
    }
    matchingReleases.sort(
      (a, b) => (0, import_date.DateParse)(b.published_at) - (0, import_date.DateParse)(a.published_at)
    );
    const latestRelease = matchingReleases[0];
    return latestRelease.tag_name;
  }, RETRY_CONFIG) ?? void 0;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  fetchReleasesViaGraphQL,
  fetchReleasesViaRest,
  getLatestRelease
});
