"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_asset_url_exports = {};
__export(github_asset_url_exports, {
  fetchReleaseAssetsViaGraphQL: () => fetchReleaseAssetsViaGraphQL,
  getReleaseAssetUrl: () => getReleaseAssetUrl
});
module.exports = __toCommonJS(github_asset_url_exports);
var import_request = require("../http-request/request");
var import_retry = require("../promises/retry");
var import_array = require("../primordials/array");
var import_error = require("../primordials/error");
var import_json = require("../primordials/json");
var import_object = require("../primordials/object");
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 fetchReleaseAssetsViaGraphQL(owner, repo, tag) {
  const response = await (0, import_request.httpRequest)("https://api.github.com/graphql", {
    body: (0, import_json.JSONStringify)({
      query: `query($owner: String!, $repo: String!, $tag: String!) {
        repository(owner: $owner, name: $repo) {
          release(tagName: $tag) {
            tagName
            releaseAssets(first: 100) { nodes { name downloadUrl } }
          }
        }
      }`,
      variables: { owner, repo, tag }
    }),
    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} release ${tag} (GraphQL): ${response.status} ${response.statusText}`
    );
  }
  if (response.body.byteLength === 0) {
    throw new import_error.ErrorCtor(
      `Failed to fetch ${owner}/${repo} release ${tag}: GraphQL returned empty body`
    );
  }
  let parsed;
  try {
    parsed = (0, import_json.JSONParse)(response.body.toString("utf8"));
  } catch (cause) {
    throw new import_error.ErrorCtor(
      `Failed to parse ${owner}/${repo} release ${tag} response (GraphQL)`,
      { cause }
    );
  }
  if (parsed.errors?.length) {
    throw new import_error.ErrorCtor(
      `GraphQL repository.release(${owner}/${repo}, ${tag}) returned errors: ${parsed.errors.map((e) => e.message).join("; ")}`
    );
  }
  const release = parsed.data?.repository?.release;
  if (!release) {
    return void 0;
  }
  return (release.releaseAssets?.nodes ?? []).map((n) => ({
    browser_download_url: n.downloadUrl,
    name: n.name
  }));
}
async function getReleaseAssetUrl(tag, assetPattern, repoConfig, options = {}) {
  const { nothrow = false } = options;
  const { owner, repo } = repoConfig;
  const isMatch = typeof assetPattern === "string" && !assetPattern.includes("*") && !assetPattern.includes("{") ? (input) => input === assetPattern : (0, import_github_assets.createAssetMatcher)(assetPattern);
  const assets = await (0, import_retry.pRetry)(async () => {
    const response = await (0, import_request.httpRequest)(
      `https://api.github.com/repos/${owner}/${repo}/releases/tags/${tag}`,
      {
        headers: (0, import_github_auth.getAuthHeaders)()
      }
    );
    if (!response.ok) {
      throw new import_error.ErrorCtor(
        `Failed to fetch ${owner}/${repo} release ${tag}: ${response.status}`
      );
    }
    let assets2;
    if (response.body.byteLength === 0) {
      let fallbackAssets;
      try {
        fallbackAssets = await fetchReleaseAssetsViaGraphQL(owner, repo, tag);
      } catch (cause) {
        if (nothrow) {
          return void 0;
        }
        throw new import_error.ErrorCtor(
          `Failed to fetch ${owner}/${repo} release ${tag}: both REST and GraphQL backends degraded`,
          { cause }
        );
      }
      if (fallbackAssets === void 0) {
        if (nothrow) {
          return void 0;
        }
        throw new import_error.ErrorCtor(`Release ${tag} not found in ${owner}/${repo}`);
      }
      assets2 = fallbackAssets;
    } else {
      let release;
      try {
        release = (0, import_json.JSONParse)(response.body.toString("utf8"));
      } catch (cause) {
        throw new import_error.ErrorCtor(
          `Failed to parse ${owner}/${repo} release ${tag} response`,
          { cause }
        );
      }
      if (!(0, import_array.ArrayIsArray)(release.assets)) {
        throw new import_error.ErrorCtor(`Release ${tag} has no assets in ${owner}/${repo}`);
      }
      assets2 = release.assets;
    }
    return assets2;
  }, RETRY_CONFIG);
  if (!assets) {
    if (nothrow) {
      return void 0;
    }
    throw new import_error.ErrorCtor(`Release ${tag} not found in ${owner}/${repo}`);
  }
  const asset = assets.find((a) => isMatch(a.name));
  if (!asset) {
    if (nothrow) {
      return void 0;
    }
    const patternDesc = typeof assetPattern === "string" ? assetPattern : "matching pattern";
    throw new import_error.ErrorCtor(`Asset ${patternDesc} not found in release ${tag}`);
  }
  return asset.browser_download_url;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  fetchReleaseAssetsViaGraphQL,
  getReleaseAssetUrl
});
