"use strict";
/* Socket Lib - Built with esbuild */
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 http_request_exports = {};
__export(http_request_exports, {
  httpDownload: () => httpDownload,
  httpGetJson: () => httpGetJson,
  httpGetText: () => httpGetText,
  httpRequest: () => httpRequest
});
module.exports = __toCommonJS(http_request_exports);
var import_fs = require("fs");
let _http;
let _https;
// @__NO_SIDE_EFFECTS__
function getHttp() {
  if (_http === void 0) {
    _http = require("node:http");
  }
  return _http;
}
// @__NO_SIDE_EFFECTS__
function getHttps() {
  if (_https === void 0) {
    _https = require("node:https");
  }
  return _https;
}
async function httpRequest(url, options) {
  const {
    body,
    followRedirects = true,
    headers = {},
    maxRedirects = 5,
    method = "GET",
    retries = 0,
    retryDelay = 1e3,
    timeout = 3e4
  } = { __proto__: null, ...options };
  let lastError;
  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      return await httpRequestAttempt(url, {
        body,
        followRedirects,
        headers,
        maxRedirects,
        method,
        timeout
      });
    } catch (e) {
      lastError = e;
      if (attempt === retries) {
        break;
      }
      const delayMs = retryDelay * 2 ** attempt;
      await new Promise((resolve) => setTimeout(resolve, delayMs));
    }
  }
  throw lastError || new Error("Request failed after retries");
}
async function httpRequestAttempt(url, options) {
  const {
    body,
    followRedirects = true,
    headers = {},
    maxRedirects = 5,
    method = "GET",
    timeout = 3e4
  } = { __proto__: null, ...options };
  return await new Promise((resolve, reject) => {
    const parsedUrl = new URL(url);
    const isHttps = parsedUrl.protocol === "https:";
    const httpModule = isHttps ? /* @__PURE__ */ getHttps() : /* @__PURE__ */ getHttp();
    const requestOptions = {
      headers: {
        "User-Agent": "socket-registry/1.0",
        ...headers
      },
      hostname: parsedUrl.hostname,
      method,
      path: parsedUrl.pathname + parsedUrl.search,
      port: parsedUrl.port,
      timeout
    };
    const request = httpModule.request(
      requestOptions,
      (res) => {
        if (followRedirects && res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
          if (maxRedirects <= 0) {
            reject(
              new Error(
                `Too many redirects (exceeded maximum: ${maxRedirects})`
              )
            );
            return;
          }
          const redirectUrl = res.headers.location.startsWith("http") ? res.headers.location : new URL(res.headers.location, url).toString();
          resolve(
            httpRequestAttempt(redirectUrl, {
              body,
              followRedirects,
              headers,
              maxRedirects: maxRedirects - 1,
              method,
              timeout
            })
          );
          return;
        }
        const chunks = [];
        res.on("data", (chunk) => {
          chunks.push(chunk);
        });
        res.on("end", () => {
          const responseBody = Buffer.concat(chunks);
          const ok = res.statusCode !== void 0 && res.statusCode >= 200 && res.statusCode < 300;
          const response = {
            arrayBuffer() {
              return responseBody.buffer.slice(
                responseBody.byteOffset,
                responseBody.byteOffset + responseBody.byteLength
              );
            },
            body: responseBody,
            headers: res.headers,
            json() {
              return JSON.parse(responseBody.toString("utf8"));
            },
            ok,
            status: res.statusCode || 0,
            statusText: res.statusMessage || "",
            text() {
              return responseBody.toString("utf8");
            }
          };
          resolve(response);
        });
      }
    );
    request.on("error", (error) => {
      const code = error.code;
      let message = `HTTP request failed for ${url}: ${error.message}
`;
      if (code === "ENOTFOUND") {
        message += "DNS lookup failed. Check the hostname and your network connection.";
      } else if (code === "ECONNREFUSED") {
        message += "Connection refused. Verify the server is running and accessible.";
      } else if (code === "ETIMEDOUT") {
        message += "Request timed out. Check your network or increase the timeout value.";
      } else if (code === "ECONNRESET") {
        message += "Connection reset. The server may have closed the connection unexpectedly.";
      } else {
        message += "Check your network connection and verify the URL is correct.";
      }
      reject(new Error(message, { cause: error }));
    });
    request.on("timeout", () => {
      request.destroy();
      reject(new Error(`Request timed out after ${timeout}ms`));
    });
    if (body) {
      request.write(body);
    }
    request.end();
  });
}
async function httpDownload(url, destPath, options) {
  const {
    headers = {},
    onProgress,
    retries = 0,
    retryDelay = 1e3,
    timeout = 12e4
  } = { __proto__: null, ...options };
  let lastError;
  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      return await httpDownloadAttempt(url, destPath, {
        headers,
        onProgress,
        timeout
      });
    } catch (e) {
      lastError = e;
      if (attempt === retries) {
        break;
      }
      const delayMs = retryDelay * 2 ** attempt;
      await new Promise((resolve) => setTimeout(resolve, delayMs));
    }
  }
  throw lastError || new Error("Download failed after retries");
}
async function httpDownloadAttempt(url, destPath, options) {
  const {
    headers = {},
    onProgress,
    timeout = 12e4
  } = { __proto__: null, ...options };
  return await new Promise((resolve, reject) => {
    const parsedUrl = new URL(url);
    const isHttps = parsedUrl.protocol === "https:";
    const httpModule = isHttps ? /* @__PURE__ */ getHttps() : /* @__PURE__ */ getHttp();
    const requestOptions = {
      headers: {
        "User-Agent": "socket-registry/1.0",
        ...headers
      },
      hostname: parsedUrl.hostname,
      method: "GET",
      path: parsedUrl.pathname + parsedUrl.search,
      port: parsedUrl.port,
      timeout
    };
    let fileStream;
    let streamClosed = false;
    const closeStream = () => {
      if (!streamClosed && fileStream) {
        streamClosed = true;
        fileStream.close();
      }
    };
    const request = httpModule.request(
      requestOptions,
      (res) => {
        if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
          closeStream();
          reject(
            new Error(
              `Download failed: HTTP ${res.statusCode} ${res.statusMessage}`
            )
          );
          return;
        }
        const totalSize = Number.parseInt(
          res.headers["content-length"] || "0",
          10
        );
        let downloadedSize = 0;
        fileStream = (0, import_fs.createWriteStream)(destPath);
        fileStream.on("error", (error) => {
          closeStream();
          const err = new Error(`Failed to write file: ${error.message}`, {
            cause: error
          });
          reject(err);
        });
        res.on("data", (chunk) => {
          downloadedSize += chunk.length;
          if (onProgress && totalSize > 0) {
            onProgress(downloadedSize, totalSize);
          }
        });
        res.on("end", () => {
          fileStream?.close(() => {
            streamClosed = true;
            resolve({
              path: destPath,
              size: downloadedSize
            });
          });
        });
        res.on("error", (error) => {
          closeStream();
          reject(error);
        });
        res.pipe(fileStream);
      }
    );
    request.on("error", (error) => {
      closeStream();
      const code = error.code;
      let message = `HTTP download failed for ${url}: ${error.message}
`;
      if (code === "ENOTFOUND") {
        message += "DNS lookup failed. Check the hostname and your network connection.";
      } else if (code === "ECONNREFUSED") {
        message += "Connection refused. Verify the server is running and accessible.";
      } else if (code === "ETIMEDOUT") {
        message += "Request timed out. Check your network or increase the timeout value.";
      } else if (code === "ECONNRESET") {
        message += "Connection reset. The server may have closed the connection unexpectedly.";
      } else {
        message += "Check your network connection and verify the URL is correct.";
      }
      reject(new Error(message, { cause: error }));
    });
    request.on("timeout", () => {
      request.destroy();
      closeStream();
      reject(new Error(`Download timed out after ${timeout}ms`));
    });
    request.end();
  });
}
async function httpGetJson(url, options) {
  const response = await httpRequest(url, { ...options, method: "GET" });
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  try {
    return response.json();
  } catch (e) {
    throw new Error("Failed to parse JSON response", { cause: e });
  }
}
async function httpGetText(url, options) {
  const response = await httpRequest(url, { ...options, method: "GET" });
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  return response.text();
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  httpDownload,
  httpGetJson,
  httpGetText,
  httpRequest
});
