"use strict";
/* 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_manifest_exports = {};
__export(dlx_manifest_exports, {
  DlxManifest: () => DlxManifest,
  dlxManifest: () => dlxManifest,
  isBinaryEntry: () => isBinaryEntry,
  isPackageEntry: () => isPackageEntry
});
module.exports = __toCommonJS(dlx_manifest_exports);
var import_fs = require("fs");
var import_path = __toESM(require("path"));
var import_fs2 = require("./fs");
var import_logger = require("./logger");
var import_socket = require("./paths/socket");
var import_process_lock = require("./process-lock");
const logger = (0, import_logger.getDefaultLogger)();
const MANIFEST_FILE_NAME = ".dlx-manifest.json";
function isPackageEntry(entry) {
  return entry.type === "package";
}
function isBinaryEntry(entry) {
  return entry.type === "binary";
}
class DlxManifest {
  manifestPath;
  lockPath;
  constructor(options = {}) {
    this.manifestPath = options.manifestPath ?? import_path.default.join((0, import_socket.getSocketDlxDir)(), MANIFEST_FILE_NAME);
    this.lockPath = `${this.manifestPath}.lock`;
  }
  /**
   * Read the entire manifest file.
   */
  readManifest() {
    try {
      if (!(0, import_fs.existsSync)(this.manifestPath)) {
        return /* @__PURE__ */ Object.create(null);
      }
      const rawContent = (0, import_fs2.readFileUtf8Sync)(this.manifestPath);
      const content = (typeof rawContent === "string" ? rawContent : rawContent.toString("utf8")).trim();
      if (!content) {
        return /* @__PURE__ */ Object.create(null);
      }
      return JSON.parse(content);
    } catch (error) {
      logger.warn(
        `Failed to read manifest: ${error instanceof Error ? error.message : String(error)}`
      );
      return /* @__PURE__ */ Object.create(null);
    }
  }
  /**
   * Get a manifest entry by spec (e.g., "@socketsecurity/cli@^2.0.11").
   */
  getManifestEntry(spec) {
    const data = this.readManifest();
    const entry = data[spec];
    if (entry && "type" in entry) {
      return entry;
    }
    return void 0;
  }
  /**
   * Get cached update information for a package (legacy format).
   * @deprecated Use getManifestEntry() for new code.
   */
  get(name) {
    const data = this.readManifest();
    const entry = data[name];
    if (entry && !("type" in entry)) {
      return entry;
    }
    return void 0;
  }
  /**
   * Set a package manifest entry.
   */
  async setPackageEntry(spec, cacheKey, details) {
    await import_process_lock.processLock.withLock(this.lockPath, async () => {
      const data = this.readManifest();
      data[spec] = {
        type: "package",
        cache_key: cacheKey,
        timestamp: Date.now(),
        details
      };
      await this.writeManifest(data);
    });
  }
  /**
   * Set a binary manifest entry.
   */
  async setBinaryEntry(spec, cacheKey, details) {
    await import_process_lock.processLock.withLock(this.lockPath, async () => {
      const data = this.readManifest();
      data[spec] = {
        type: "binary",
        cache_key: cacheKey,
        timestamp: Date.now(),
        details
      };
      await this.writeManifest(data);
    });
  }
  /**
   * Write the manifest file atomically.
   */
  async writeManifest(data) {
    const manifestDir = import_path.default.dirname(this.manifestPath);
    try {
      (0, import_fs2.safeMkdirSync)(manifestDir, { recursive: true });
    } catch (error) {
      logger.warn(
        `Failed to create manifest directory: ${error instanceof Error ? error.message : String(error)}`
      );
    }
    const content = JSON.stringify(data, null, 2);
    const tempPath = `${this.manifestPath}.tmp`;
    try {
      (0, import_fs.writeFileSync)(tempPath, content, "utf8");
      (0, import_fs.writeFileSync)(this.manifestPath, content, "utf8");
      try {
        if ((0, import_fs.existsSync)(tempPath)) {
          (0, import_fs.unlinkSync)(tempPath);
        }
      } catch {
      }
    } catch (error) {
      try {
        if ((0, import_fs.existsSync)(tempPath)) {
          (0, import_fs.unlinkSync)(tempPath);
        }
      } catch {
      }
      throw error;
    }
  }
  /**
   * Store update information for a package (legacy format).
   * @deprecated Use setPackageEntry() for new code.
   */
  async set(name, record) {
    await import_process_lock.processLock.withLock(this.lockPath, async () => {
      let data = /* @__PURE__ */ Object.create(null);
      try {
        if ((0, import_fs.existsSync)(this.manifestPath)) {
          const content2 = (0, import_fs.readFileSync)(this.manifestPath, "utf8");
          if (content2.trim()) {
            data = JSON.parse(content2);
          }
        }
      } catch (error) {
        logger.warn(
          `Failed to read existing manifest: ${error instanceof Error ? error.message : String(error)}`
        );
      }
      data[name] = record;
      const manifestDir = import_path.default.dirname(this.manifestPath);
      try {
        (0, import_fs2.safeMkdirSync)(manifestDir, { recursive: true });
      } catch (error) {
        logger.warn(
          `Failed to create manifest directory: ${error instanceof Error ? error.message : String(error)}`
        );
      }
      const content = JSON.stringify(data, null, 2);
      const tempPath = `${this.manifestPath}.tmp`;
      try {
        (0, import_fs.writeFileSync)(tempPath, content, "utf8");
        (0, import_fs.writeFileSync)(this.manifestPath, content, "utf8");
        try {
          if ((0, import_fs.existsSync)(tempPath)) {
            (0, import_fs.unlinkSync)(tempPath);
          }
        } catch {
        }
      } catch (error) {
        try {
          if ((0, import_fs.existsSync)(tempPath)) {
            (0, import_fs.unlinkSync)(tempPath);
          }
        } catch {
        }
        throw error;
      }
    });
  }
  /**
   * Clear cached data for a specific entry.
   */
  async clear(name) {
    await import_process_lock.processLock.withLock(this.lockPath, async () => {
      try {
        if (!(0, import_fs.existsSync)(this.manifestPath)) {
          return;
        }
        const content = (0, import_fs.readFileSync)(this.manifestPath, "utf8");
        if (!content.trim()) {
          return;
        }
        const data = JSON.parse(content);
        delete data[name];
        const updatedContent = JSON.stringify(data, null, 2);
        (0, import_fs.writeFileSync)(this.manifestPath, updatedContent, "utf8");
      } catch (error) {
        logger.warn(
          `Failed to clear cache for ${name}: ${error instanceof Error ? error.message : String(error)}`
        );
      }
    });
  }
  /**
   * Clear all cached data.
   */
  async clearAll() {
    await import_process_lock.processLock.withLock(this.lockPath, async () => {
      try {
        if ((0, import_fs.existsSync)(this.manifestPath)) {
          (0, import_fs.unlinkSync)(this.manifestPath);
        }
      } catch (error) {
        logger.warn(
          `Failed to clear all cache: ${error instanceof Error ? error.message : String(error)}`
        );
      }
    });
  }
  /**
   * Check if cached data is fresh based on TTL.
   */
  isFresh(record, ttlMs) {
    if (!record) {
      return false;
    }
    const age = Date.now() - record.timestampFetch;
    return age < ttlMs;
  }
  /**
   * Get all cached package names.
   */
  getAllPackages() {
    try {
      if (!(0, import_fs.existsSync)(this.manifestPath)) {
        return [];
      }
      const rawContent = (0, import_fs2.readFileUtf8Sync)(this.manifestPath);
      const content = (typeof rawContent === "string" ? rawContent : rawContent.toString("utf8")).trim();
      if (!content) {
        return [];
      }
      const data = JSON.parse(content);
      return Object.keys(data);
    } catch (error) {
      logger.warn(
        `Failed to get package list: ${error instanceof Error ? error.message : String(error)}`
      );
      return [];
    }
  }
}
const dlxManifest = new DlxManifest();
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  DlxManifest,
  dlxManifest,
  isBinaryEntry,
  isPackageEntry
});
