"use strict";
/* Socket Lib - Built with esbuild */
"use strict";
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 check_primordials_exports = {};
__export(check_primordials_exports, {
  loadConfig: () => loadConfig,
  parseArgs: () => parseArgs,
  printHelp: () => printHelp,
  renderHuman: () => renderHuman,
  resolveConfigPath: () => resolveConfigPath,
  runCheckPrimordials: () => runCheckPrimordials,
  serialize: () => serialize
});
module.exports = __toCommonJS(check_primordials_exports);
var import_node_fs = require("node:fs");
var import_node_path = __toESM(require("node:path"));
var import_node_process = __toESM(require("node:process"));
var import_message = require("../errors/message");
var import_logger = require("../logger/logger");
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_primordials = require("../checks/primordials");
var import_parse = require("../argv/parse");
const logger = (0, import_logger.getDefaultLogger)();
const DEFAULT_CONFIG_PATH = ".socket-lib.json";
const FALLBACK_CONFIG_PATHS = [
  ".socket-lib.json",
  ".config/socket-lib.json"
];
const CONFIG_SECTION = "primordials";
function parseArgs(argv) {
  const { values } = (0, import_parse.parseArgs)({
    args: argv,
    strict: false,
    options: {
      config: { type: "string", short: "c" },
      explain: { type: "boolean" },
      help: { type: "boolean", short: "h" },
      json: { type: "boolean" },
      silent: { type: "boolean" }
    }
  });
  const explicitConfig = values["config"];
  return {
    config: typeof explicitConfig === "string" ? explicitConfig : void 0,
    json: Boolean(values["json"]),
    explain: Boolean(values["explain"]),
    silent: Boolean(values["silent"]),
    help: Boolean(values["help"])
  };
}
function resolveConfigPath(explicit) {
  if (explicit !== void 0) {
    return explicit;
  }
  for (const candidate of FALLBACK_CONFIG_PATHS) {
    if ((0, import_node_fs.existsSync)(import_node_path.default.resolve(candidate))) {
      return candidate;
    }
  }
  return FALLBACK_CONFIG_PATHS[0];
}
function printHelp() {
  logger.log("socket-lib check primordials \u2014 primordials drift check");
  logger.log("");
  logger.log("Usage:");
  logger.log("  socket-lib check primordials [opts]");
  logger.log("  socket-lib check prim        [opts]    # short alias");
  logger.log("");
  logger.log("Options:");
  logger.log(
    `  --config, -c <path>   Config file. Default: ${DEFAULT_CONFIG_PATH}`
  );
  logger.log(`                        (falls back to .config/socket-lib.json)`);
  logger.log("  --explain             Print one detailed line per finding.");
  logger.log("  --json                Machine-readable JSON output.");
  logger.log("  --silent              Silent on success.");
  logger.log("  --help, -h            Print this help.");
  logger.log("");
  logger.log("Config (.socket-lib.json \u2014 primordials section):");
  logger.log("  {");
  logger.log('    "primordials": {');
  logger.log('      "aliasMap":         { "Array": "ArrayCtor" },');
  logger.log('      "nodeInternalOnly": ["SafeMap", "SafeSet"],');
  logger.log(
    '      "scanDirs":         ["src", "additions/source-patched/lib"]'
  );
  logger.log("    }");
  logger.log("  }");
  logger.log("");
  logger.log("A bare object (no `primordials` section) is also accepted for");
  logger.log("repos that only run this one check.");
}
function loadConfig(configPath) {
  if (!(0, import_node_fs.existsSync)(configPath)) {
    throw new import_error.ErrorCtor(`config file not found: ${configPath}`);
  }
  let parsed;
  try {
    parsed = (0, import_json.JSONParse)((0, import_node_fs.readFileSync)(configPath, "utf8"));
  } catch (e) {
    throw new import_error.ErrorCtor(`config file is not valid JSON: ${(0, import_message.errorMessage)(e)}`);
  }
  if (typeof parsed !== "object" || parsed === null || (0, import_array.ArrayIsArray)(parsed)) {
    throw new import_error.ErrorCtor("config root must be an object");
  }
  const root = parsed;
  const sectional = root[CONFIG_SECTION];
  const raw = sectional !== void 0 ? sectional : root;
  if (!(0, import_array.ArrayIsArray)(raw.scanDirs)) {
    throw new import_error.ErrorCtor(
      `config.scanDirs must be an array of strings (got ${typeof raw.scanDirs})`
    );
  }
  for (const [i, v] of raw.scanDirs.entries()) {
    if (typeof v !== "string") {
      throw new import_error.ErrorCtor(`config.scanDirs[${i}] must be a string`);
    }
  }
  if (raw.aliasMap !== void 0 && (typeof raw.aliasMap !== "object" || raw.aliasMap === null || (0, import_array.ArrayIsArray)(raw.aliasMap))) {
    throw new import_error.ErrorCtor("config.aliasMap must be an object of source\u2192target");
  }
  if (raw.nodeInternalOnly !== void 0 && !(0, import_array.ArrayIsArray)(raw.nodeInternalOnly)) {
    throw new import_error.ErrorCtor("config.nodeInternalOnly must be an array of strings");
  }
  const aliasMap = new Map(
    (0, import_object.ObjectEntries)(raw.aliasMap ?? {})
  );
  const nodeInternalOnly = new Set(
    (raw.nodeInternalOnly ?? []).filter(
      (x) => typeof x === "string"
    )
  );
  return {
    scanDirs: raw.scanDirs,
    aliasMap,
    nodeInternalOnly,
    socketLibPrimordialsPath: typeof raw.socketLibPrimordialsPath === "string" ? raw.socketLibPrimordialsPath : void 0,
    repoRoot: import_node_process.default.cwd()
  };
}
function serialize(result) {
  return {
    ok: result.findings.length === 0,
    used: result.used.size,
    findings: result.findings.map((f) => ({
      kind: f.kind,
      name: f.name,
      files: f.files,
      hint: f.hint
    }))
  };
}
function renderHuman(result, args) {
  if (result.findings.length === 0) {
    if (!args.silent) {
      logger.success(
        `Primordials coverage OK \u2014 ${result.used.size} names used, all accounted for.`
      );
    }
    return;
  }
  logger.error(
    `Primordials drift detected \u2014 ${result.findings.length} unaccounted name(s):`
  );
  for (const f of result.findings) {
    logger.error(`  ${f.name}`);
    if (args.explain) {
      logger.error(`    ${f.hint}`);
      if (f.files.length > 0) {
        logger.error(`    files: ${f.files.join(", ")}`);
      }
    }
  }
  if (!args.explain) {
    logger.error("");
    logger.error("Run with --explain for fix instructions and file references.");
  }
}
async function runCheckPrimordials(argv) {
  const args = parseArgs(argv);
  if (args.help) {
    printHelp();
    return 0;
  }
  let config;
  try {
    config = loadConfig(import_node_path.default.resolve(resolveConfigPath(args.config)));
  } catch (e) {
    logger.error(`socket-lib check primordials: ${(0, import_message.errorMessage)(e)}`);
    return 1;
  }
  let result;
  try {
    result = (0, import_primordials.checkPrimordials)(config);
  } catch (e) {
    logger.error(`socket-lib check primordials: ${(0, import_message.errorMessage)(e)}`);
    return 1;
  }
  if (args.json) {
    logger.log((0, import_json.JSONStringify)(serialize(result), null, 2));
  } else {
    renderHuman(result, args);
  }
  return result.findings.length === 0 ? 0 : 1;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  loadConfig,
  parseArgs,
  printHelp,
  renderHuman,
  resolveConfigPath,
  runCheckPrimordials,
  serialize
});
