"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 ipc_exports = {};
__export(ipc_exports, {
  IpcHandshakeSchema: () => IpcHandshakeSchema,
  cleanupIpcStubs: () => cleanupIpcStubs,
  createIpcChannelId: () => createIpcChannelId,
  createIpcMessage: () => createIpcMessage,
  getIpcStubPath: () => getIpcStubPath,
  hasIpcChannel: () => hasIpcChannel,
  onIpc: () => onIpc,
  parseIpcMessage: () => parseIpcMessage,
  readIpcStub: () => readIpcStub,
  sendIpc: () => sendIpc,
  waitForIpc: () => waitForIpc,
  writeIpcStub: () => writeIpcStub
});
module.exports = __toCommonJS(ipc_exports);
var import_crypto = __toESM(require("crypto"));
var import_fs = require("fs");
var import_path = __toESM(require("path"));
var import_fs2 = require("./fs");
var import_socket = require("./paths/socket");
var import_zod = require("./zod");
const IpcMessageSchema = import_zod.z.object({
  /** Unique identifier for message tracking and response correlation. */
  id: import_zod.z.string().min(1),
  /** Unix timestamp for freshness validation and replay prevention. */
  timestamp: import_zod.z.number().positive(),
  /** Message type identifier for routing and handling. */
  type: import_zod.z.string().min(1),
  /** Payload data - can be any JSON-serializable value. */
  data: import_zod.z.unknown()
});
const IpcHandshakeSchema = IpcMessageSchema.extend({
  type: import_zod.z.literal("handshake"),
  data: import_zod.z.object({
    /** Protocol version for compatibility checking. */
    version: import_zod.z.string(),
    /** Process ID for identification. */
    pid: import_zod.z.number().int().positive(),
    /** Optional API token for authentication. */
    apiToken: import_zod.z.string().optional(),
    /** Application name for multi-app support. */
    appName: import_zod.z.string()
  })
});
const IpcStubSchema = import_zod.z.object({
  /** Process ID that created the stub. */
  pid: import_zod.z.number().int().positive(),
  /** Creation timestamp for age validation. */
  timestamp: import_zod.z.number().positive(),
  /** The actual data payload. */
  data: import_zod.z.unknown()
});
function createIpcChannelId(prefix = "socket") {
  return `${prefix}-${process.pid}-${import_crypto.default.randomBytes(8).toString("hex")}`;
}
function getIpcStubPath(appName) {
  const tempDir = (0, import_socket.getOsTmpDir)();
  const stubDir = import_path.default.join(tempDir, ".socket-ipc", appName);
  return import_path.default.join(stubDir, `stub-${process.pid}.json`);
}
async function ensureIpcDirectory(filePath) {
  const dir = import_path.default.dirname(filePath);
  await import_fs.promises.mkdir(dir, { recursive: true });
}
async function writeIpcStub(appName, data) {
  const stubPath = getIpcStubPath(appName);
  await ensureIpcDirectory(stubPath);
  const ipcData = {
    data,
    pid: process.pid,
    timestamp: Date.now()
  };
  const validated = IpcStubSchema.parse(ipcData);
  await import_fs.promises.writeFile(stubPath, JSON.stringify(validated, null, 2), "utf8");
  return stubPath;
}
async function readIpcStub(stubPath) {
  try {
    const content = await import_fs.promises.readFile(stubPath, "utf8");
    const parsed = JSON.parse(content);
    const validated = IpcStubSchema.parse(parsed);
    const ageMs = Date.now() - validated.timestamp;
    const maxAgeMs = 5 * 60 * 1e3;
    if (ageMs > maxAgeMs) {
      try {
        (0, import_fs2.safeDeleteSync)(stubPath, { force: true });
      } catch {
      }
      return null;
    }
    return validated.data;
  } catch {
    return null;
  }
}
async function cleanupIpcStubs(appName) {
  const tempDir = (0, import_socket.getOsTmpDir)();
  const stubDir = import_path.default.join(tempDir, ".socket-ipc", appName);
  try {
    const files = await import_fs.promises.readdir(stubDir);
    const now = Date.now();
    const maxAgeMs = 5 * 60 * 1e3;
    await Promise.allSettled(
      files.map(async (file) => {
        if (file.startsWith("stub-") && file.endsWith(".json")) {
          const filePath = import_path.default.join(stubDir, file);
          try {
            const stats = await import_fs.promises.stat(filePath);
            const mtimeAge = now - stats.mtimeMs;
            let isStale = mtimeAge > maxAgeMs;
            try {
              const content = await import_fs.promises.readFile(filePath, "utf8");
              const parsed = JSON.parse(content);
              const validated = IpcStubSchema.parse(parsed);
              const contentAge = now - validated.timestamp;
              isStale = isStale || contentAge > maxAgeMs;
            } catch {
            }
            if (isStale) {
              (0, import_fs2.safeDeleteSync)(filePath, { force: true });
            }
          } catch {
          }
        }
      })
    );
  } catch {
  }
}
function sendIpc(process2, message) {
  if (process2 && typeof process2 === "object" && "send" in process2 && typeof process2.send === "function") {
    try {
      const validated = IpcMessageSchema.parse(message);
      return process2.send(validated);
    } catch {
      return false;
    }
  }
  return false;
}
function onIpc(handler) {
  const listener = (message) => {
    const parsed = parseIpcMessage(message);
    if (parsed) {
      handler(parsed);
    }
  };
  process.on("message", listener);
  return () => {
    process.off("message", listener);
  };
}
function waitForIpc(messageType, options = {}) {
  const { timeout = 3e4 } = options;
  return new Promise((resolve, reject) => {
    let cleanup = null;
    let timeoutId = null;
    const handleTimeout = () => {
      if (cleanup) {
        cleanup();
      }
      reject(new Error(`IPC timeout waiting for message type: ${messageType}`));
    };
    const handleMessage = (message) => {
      if (message.type === messageType) {
        if (timeoutId) {
          clearTimeout(timeoutId);
        }
        if (cleanup) {
          cleanup();
        }
        resolve(message.data);
      }
    };
    cleanup = onIpc(handleMessage);
    if (timeout > 0) {
      timeoutId = setTimeout(handleTimeout, timeout);
    }
  });
}
function createIpcMessage(type, data) {
  return {
    id: import_crypto.default.randomBytes(16).toString("hex"),
    timestamp: Date.now(),
    type,
    data
  };
}
function hasIpcChannel(process2) {
  return Boolean(
    process2 && typeof process2 === "object" && "send" in process2 && typeof process2.send === "function" && "channel" in process2 && process2.channel !== void 0
  );
}
function parseIpcMessage(message) {
  try {
    const validated = IpcMessageSchema.parse(message);
    return validated;
  } catch {
    return null;
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  IpcHandshakeSchema,
  cleanupIpcStubs,
  createIpcChannelId,
  createIpcMessage,
  getIpcStubPath,
  hasIpcChannel,
  onIpc,
  parseIpcMessage,
  readIpcStub,
  sendIpc,
  waitForIpc,
  writeIpcStub
});
