/* Socket Lib - Built with esbuild */
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var dlx_binary_exports = {};
__export(dlx_binary_exports, {
  cleanDlxCache: () => cleanDlxCache,
  dlxBinary: () => dlxBinary,
  getDlxCachePath: () => getDlxCachePath,
  listDlxCache: () => listDlxCache
});
module.exports = __toCommonJS(dlx_binary_exports);
var import_node_crypto = require("node:crypto");
var import_node_fs = require("node:fs");
var import_node_os = __toESM(require("node:os"));
var import_node_path = __toESM(require("node:path"));
var import_platform = require("#constants/platform");
var import_fs = require("./fs");
var import_http_request = require("./http-request");
var import_objects = require("./objects");
var import_path = require("./path");
var import_paths = require("./paths");
var import_spawn = require("./spawn");
function generateCacheKey(url) {
  return (0, import_node_crypto.createHash)("sha256").update(url).digest("hex");
}
function getMetadataPath(cacheEntryPath) {
  return import_node_path.default.join(cacheEntryPath, ".dlx-metadata.json");
}
async function isCacheValid(cacheEntryPath, cacheTtl) {
  try {
    const metaPath = getMetadataPath(cacheEntryPath);
    if (!(0, import_node_fs.existsSync)(metaPath)) {
      return false;
    }
    const metadata = await (0, import_fs.readJson)(metaPath, { throws: false });
    if (!(0, import_objects.isObjectObject)(metadata)) {
      return false;
    }
    const now = Date.now();
    const age = now - (metadata["timestamp"] || 0);
    return age < cacheTtl;
  } catch {
    return false;
  }
}
async function downloadBinary(url, destPath, checksum) {
  const response = await (0, import_http_request.httpRequest)(url);
  if (!response.ok) {
    throw new Error(
      `Failed to download binary: ${response.status} ${response.statusText}`
    );
  }
  const tempPath = `${destPath}.download`;
  const hasher = (0, import_node_crypto.createHash)("sha256");
  try {
    await import_node_fs.promises.mkdir(import_node_path.default.dirname(destPath), { recursive: true });
    const buffer = response.body;
    hasher.update(buffer);
    const actualChecksum = hasher.digest("hex");
    if (checksum && actualChecksum !== checksum) {
      throw new Error(
        `Checksum mismatch: expected ${checksum}, got ${actualChecksum}`
      );
    }
    await import_node_fs.promises.writeFile(tempPath, buffer);
    if (!import_platform.WIN32) {
      await import_node_fs.promises.chmod(tempPath, 493);
    }
    await import_node_fs.promises.rename(tempPath, destPath);
    return actualChecksum;
  } catch (e) {
    try {
      await (0, import_fs.safeDelete)(tempPath);
    } catch {
    }
    throw e;
  }
}
async function writeMetadata(cacheEntryPath, url, checksum) {
  const metaPath = getMetadataPath(cacheEntryPath);
  const metadata = {
    arch: import_node_os.default.arch(),
    checksum,
    platform: import_node_os.default.platform(),
    timestamp: Date.now(),
    url,
    version: "1.0.0"
  };
  await import_node_fs.promises.writeFile(metaPath, JSON.stringify(metadata, null, 2));
}
async function cleanDlxCache(maxAge = (
  /*@__INLINE__*/
  require("./constants/time").DLX_BINARY_CACHE_TTL
)) {
  const cacheDir = getDlxCachePath();
  if (!(0, import_node_fs.existsSync)(cacheDir)) {
    return 0;
  }
  let cleaned = 0;
  const now = Date.now();
  const entries = await import_node_fs.promises.readdir(cacheDir);
  for (const entry of entries) {
    const entryPath = import_node_path.default.join(cacheDir, entry);
    const metaPath = getMetadataPath(entryPath);
    try {
      if (!await (0, import_fs.isDir)(entryPath)) {
        continue;
      }
      const metadata = await (0, import_fs.readJson)(metaPath, { throws: false });
      if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
        continue;
      }
      const age = now - (metadata["timestamp"] || 0);
      if (age > maxAge) {
        await (0, import_fs.safeDelete)(entryPath, { force: true, recursive: true });
        cleaned += 1;
      }
    } catch {
      try {
        const contents = await import_node_fs.promises.readdir(entryPath);
        if (!contents.length) {
          await (0, import_fs.safeDelete)(entryPath);
          cleaned += 1;
        }
      } catch {
      }
    }
  }
  return cleaned;
}
async function dlxBinary(args, options, spawnExtra) {
  const {
    cacheTtl = (
      /*@__INLINE__*/
      require("./constants/time").DLX_BINARY_CACHE_TTL
    ),
    checksum,
    force = false,
    name,
    spawnOptions,
    url
  } = { __proto__: null, ...options };
  const cacheDir = getDlxCachePath();
  const cacheKey = generateCacheKey(url);
  const cacheEntryDir = import_node_path.default.join(cacheDir, cacheKey);
  const binaryName = name || `binary-${process.platform}-${import_node_os.default.arch()}`;
  const binaryPath = (0, import_path.normalizePath)(import_node_path.default.join(cacheEntryDir, binaryName));
  let downloaded = false;
  let computedChecksum = checksum;
  if (!force && (0, import_node_fs.existsSync)(cacheEntryDir) && await isCacheValid(cacheEntryDir, cacheTtl)) {
    try {
      const metaPath = getMetadataPath(cacheEntryDir);
      const metadata = await (0, import_fs.readJson)(metaPath, { throws: false });
      if (metadata && typeof metadata === "object" && !Array.isArray(metadata) && typeof metadata["checksum"] === "string") {
        computedChecksum = metadata["checksum"];
      } else {
        downloaded = true;
      }
    } catch {
      downloaded = true;
    }
  } else {
    downloaded = true;
  }
  if (downloaded) {
    await import_node_fs.promises.mkdir(cacheEntryDir, { recursive: true });
    computedChecksum = await downloadBinary(url, binaryPath, checksum);
    await writeMetadata(cacheEntryDir, url, computedChecksum || "");
  }
  const needsShell = import_platform.WIN32 && /\.(?:bat|cmd|ps1)$/i.test(binaryPath);
  const finalSpawnOptions = needsShell ? {
    ...spawnOptions,
    env: {
      ...spawnOptions?.env,
      PATH: `${cacheEntryDir}${import_node_path.default.delimiter}${process.env["PATH"] || ""}`
    },
    shell: true
  } : spawnOptions;
  const spawnPromise = (0, import_spawn.spawn)(binaryPath, args, finalSpawnOptions, spawnExtra);
  return {
    binaryPath,
    downloaded,
    spawnPromise
  };
}
function getDlxCachePath() {
  return (0, import_paths.getSocketDlxDir)();
}
async function listDlxCache() {
  const cacheDir = getDlxCachePath();
  if (!(0, import_node_fs.existsSync)(cacheDir)) {
    return [];
  }
  const results = [];
  const now = Date.now();
  const entries = await import_node_fs.promises.readdir(cacheDir);
  for (const entry of entries) {
    const entryPath = import_node_path.default.join(cacheDir, entry);
    try {
      if (!await (0, import_fs.isDir)(entryPath)) {
        continue;
      }
      const metaPath = getMetadataPath(entryPath);
      const metadata = await (0, import_fs.readJson)(metaPath, { throws: false });
      if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
        continue;
      }
      const files = await import_node_fs.promises.readdir(entryPath);
      const binaryFile = files.find((f) => !f.startsWith("."));
      if (binaryFile) {
        const binaryPath = import_node_path.default.join(entryPath, binaryFile);
        const binaryStats = await import_node_fs.promises.stat(binaryPath);
        const metaObj = metadata;
        results.push({
          age: now - (metaObj["timestamp"] || 0),
          arch: metaObj["arch"] || "unknown",
          checksum: metaObj["checksum"] || "",
          name: binaryFile,
          platform: metaObj["platform"] || "unknown",
          size: binaryStats.size,
          url: metaObj["url"] || ""
        });
      }
    } catch {
    }
  }
  return results;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  cleanDlxCache,
  dlxBinary,
  getDlxCachePath,
  listDlxCache
});
//# sourceMappingURL=dlx-binary.js.map
