"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 manifest_exports = {};
__export(manifest_exports, {
  DlxManifest: () => DlxManifest,
  dlxManifest: () => dlxManifest,
  isBinaryEntry: () => isBinaryEntry,
  isPackageEntry: () => isPackageEntry
});
module.exports = __toCommonJS(manifest_exports);
var import_message = require("../errors/message");
var import_read_file = require("../fs/read-file");
var import_safe = require("../fs/safe");
var import_logger = require("../logger/logger");
var import_socket = require("../paths/socket");
var import_lock_instance = require("../process/lock-instance");
var import_date = require("../primordials/date");
var import_json = require("../primordials/json");
var import_object = require("../primordials/object");
var import_fs = require("../node/fs");
var import_path = require("../node/path");
const fs = (0, import_fs.getNodeFs)();
const path = (0, import_path.getNodePath)();
const logger = (0, import_logger.getDefaultLogger)();
const MANIFEST_FILE_NAME = ".dlx-manifest.json";
function isBinaryEntry(entry) {
  return entry.type === "binary";
}
function isPackageEntry(entry) {
  return entry.type === "package";
}
class DlxManifest {
  manifestPath;
  lockPath;
  constructor(options = {}) {
    this.manifestPath = options.manifestPath ?? path.join((0, import_socket.getSocketDlxDir)(), MANIFEST_FILE_NAME);
    this.lockPath = `${this.manifestPath}.lock`;
  }
  /**
   * Read the entire manifest file.
   *
   * @private
   */
  readManifest() {
    try {
      if (!fs.existsSync(this.manifestPath)) {
        return { __proto__: null };
      }
      const rawContent = (0, import_read_file.readFileUtf8Sync)(this.manifestPath);
      const content = (typeof rawContent === "string" ? rawContent : (
        /* c8 ignore next - readFileUtf8Sync returns string in tests; Buffer fallback. */
        rawContent.toString("utf8")
      )).trim();
      if (!content) {
        return { __proto__: null };
      }
      return (0, import_json.JSONParse)(content);
    } catch (e) {
      logger.warn(`Failed to read manifest: ${(0, import_message.errorMessage)(e)}`);
      return { __proto__: null };
    }
  }
  /**
   * Write the manifest file atomically.
   *
   * @private
   */
  async writeManifest(data) {
    const manifestDir = path.dirname(this.manifestPath);
    try {
      (0, import_safe.safeMkdirSync)(manifestDir, { recursive: true });
    } catch (e) {
      logger.warn(`Failed to create manifest directory: ${(0, import_message.errorMessage)(e)}`);
    }
    const content = (0, import_json.JSONStringify)(data, void 0, 2);
    const tempPath = `${this.manifestPath}.tmp`;
    try {
      fs.writeFileSync(tempPath, content, "utf8");
      fs.renameSync(tempPath, this.manifestPath);
    } catch (e) {
      try {
        if (fs.existsSync(tempPath)) {
          (0, import_safe.safeDeleteSync)(tempPath);
        }
      } catch {
      }
      throw e;
    }
  }
  /**
   * Clear cached data for a specific entry.
   */
  async clear(name) {
    await import_lock_instance.processLock.withLock(this.lockPath, async () => {
      try {
        if (!fs.existsSync(this.manifestPath)) {
          return;
        }
        const content = fs.readFileSync(this.manifestPath, "utf8");
        if (!content.trim()) {
          return;
        }
        const data = (0, import_json.JSONParse)(content);
        delete data[name];
        await this.writeManifest(data);
      } catch (e) {
        logger.warn(`Failed to clear cache for ${name}: ${(0, import_message.errorMessage)(e)}`);
      }
    });
  }
  /**
   * Clear all cached data.
   */
  async clearAll() {
    await import_lock_instance.processLock.withLock(this.lockPath, async () => {
      try {
        if (fs.existsSync(this.manifestPath)) {
          (0, import_safe.safeDeleteSync)(this.manifestPath);
        }
      } catch (e) {
        logger.warn(`Failed to clear all cache: ${(0, import_message.errorMessage)(e)}`);
      }
    });
  }
  /**
   * 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;
  }
  /**
   * Get all cached package names.
   */
  getAllPackages() {
    try {
      if (!fs.existsSync(this.manifestPath)) {
        return [];
      }
      const rawContent = (0, import_read_file.readFileUtf8Sync)(this.manifestPath);
      const content = (typeof rawContent === "string" ? rawContent : (
        /* c8 ignore next - readFileUtf8Sync returns string in tests; Buffer fallback. */
        rawContent.toString("utf8")
      )).trim();
      if (!content) {
        return [];
      }
      const data = (0, import_json.JSONParse)(content);
      return (0, import_object.ObjectKeys)(data);
    } catch (e) {
      logger.warn(`Failed to get package list: ${(0, import_message.errorMessage)(e)}`);
      return [];
    }
  }
  /**
   * 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;
  }
  /**
   * Check if cached data is fresh based on TTL.
   */
  isFresh(record, ttlMs) {
    if (!record) {
      return false;
    }
    const age = (0, import_date.DateNow)() - record.timestampFetch;
    return age < ttlMs;
  }
  /**
   * Store update information for a package (legacy format).
   *
   * @deprecated Use setPackageEntry() for new code.
   */
  async set(name, record) {
    await import_lock_instance.processLock.withLock(this.lockPath, async () => {
      let data = {
        __proto__: null
      };
      try {
        if (fs.existsSync(this.manifestPath)) {
          const content2 = fs.readFileSync(this.manifestPath, "utf8");
          if (content2.trim()) {
            data = (0, import_json.JSONParse)(content2);
          }
        }
      } catch (e) {
        logger.warn(`Failed to read existing manifest: ${(0, import_message.errorMessage)(e)}`);
      }
      data[name] = record;
      const manifestDir = path.dirname(this.manifestPath);
      try {
        (0, import_safe.safeMkdirSync)(manifestDir, { recursive: true });
      } catch (e) {
        logger.warn(`Failed to create manifest directory: ${(0, import_message.errorMessage)(e)}`);
      }
      const content = (0, import_json.JSONStringify)(data, null, 2);
      const tempPath = `${this.manifestPath}.tmp`;
      try {
        fs.writeFileSync(tempPath, content, "utf8");
        fs.renameSync(tempPath, this.manifestPath);
      } catch (e) {
        try {
          if (fs.existsSync(tempPath)) {
            (0, import_safe.safeDeleteSync)(tempPath);
          }
        } catch {
        }
        throw e;
      }
    });
  }
  /**
   * Set a binary manifest entry.
   */
  async setBinaryEntry(spec, cacheKey, details) {
    await import_lock_instance.processLock.withLock(this.lockPath, async () => {
      const data = this.readManifest();
      data[spec] = {
        type: "binary",
        cache_key: cacheKey,
        timestamp: Date.now(),
        details
      };
      await this.writeManifest(data);
    });
  }
  /**
   * Set a package manifest entry.
   */
  async setPackageEntry(spec, cacheKey, details) {
    await import_lock_instance.processLock.withLock(this.lockPath, async () => {
      const data = this.readManifest();
      data[spec] = {
        type: "package",
        cache_key: cacheKey,
        timestamp: Date.now(),
        details
      };
      await this.writeManifest(data);
    });
  }
}
const dlxManifest = new DlxManifest();
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  DlxManifest,
  dlxManifest,
  isBinaryEntry,
  isPackageEntry
});
