import { r as formatErrorMessage } from "./errors-CGMew-1w.js";
import { i as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIT1-v_a.js";
import { i as openBoundaryFileSync } from "./boundary-file-read-yTFhgtfy.js";
import { n as resolveKaijiBotPackageRootSync } from "./kaijibot-root-DrKPBBQD.js";
import { t as createSubsystemLogger } from "./subsystem-qDUB67UD.js";
import { n as buildPluginLoaderJitiOptions, u as resolvePluginLoaderJitiConfig } from "./sdk-alias-Czt6OgXf.js";
import { n as listBundledPluginMetadata, r as resolveBundledPluginGeneratedPath } from "./bundled-plugin-metadata-AEhTUUZp.js";
import { createRequire } from "node:module";
import { fileURLToPath } from "node:url";
import fs from "node:fs";
import path from "node:path";
import { createJiti } from "jiti";
//#region src/plugins/bundled-channel-runtime.ts
function listBundledChannelPluginMetadata(params) {
	return listBundledPluginMetadata(params);
}
function resolveBundledChannelGeneratedPath(rootDir, entry, pluginDirName) {
	return resolveBundledPluginGeneratedPath(rootDir, entry, pluginDirName);
}
//#endregion
//#region src/channels/plugins/module-loader.ts
const nodeRequire = createRequire(import.meta.url);
function createModuleLoader() {
	const jitiLoaders = /* @__PURE__ */ new Map();
	return (modulePath) => {
		const { tryNative, aliasMap, cacheKey } = resolvePluginLoaderJitiConfig({
			modulePath,
			argv1: process.argv[1],
			moduleUrl: import.meta.url,
			preferBuiltDist: true
		});
		const cached = jitiLoaders.get(cacheKey);
		if (cached) return cached;
		const loader = createJiti(import.meta.url, {
			...buildPluginLoaderJitiOptions(aliasMap),
			tryNative
		});
		jitiLoaders.set(cacheKey, loader);
		return loader;
	};
}
let loadModule = createModuleLoader();
function isJavaScriptModulePath(modulePath) {
	return [
		".js",
		".mjs",
		".cjs"
	].includes(normalizeLowercaseStringOrEmpty(path.extname(modulePath)));
}
function resolvePluginModuleCandidates(rootDir, specifier) {
	const normalizedSpecifier = specifier.replace(/\\/g, "/");
	const resolvedPath = path.resolve(rootDir, normalizedSpecifier);
	if (path.extname(resolvedPath)) return [resolvedPath];
	return [
		resolvedPath,
		`${resolvedPath}.ts`,
		`${resolvedPath}.js`,
		`${resolvedPath}.mjs`,
		`${resolvedPath}.cjs`
	];
}
function resolveExistingPluginModulePath(rootDir, specifier) {
	for (const candidate of resolvePluginModuleCandidates(rootDir, specifier)) if (fs.existsSync(candidate)) return candidate;
	return path.resolve(rootDir, specifier);
}
function loadChannelPluginModule(params) {
	const opened = openBoundaryFileSync({
		absolutePath: params.modulePath,
		rootPath: params.boundaryRootDir ?? params.rootDir,
		boundaryLabel: params.boundaryLabel ?? "plugin root",
		rejectHardlinks: false,
		skipLexicalRootCheck: true
	});
	if (!opened.ok) throw new Error(`${params.boundaryLabel ?? "plugin"} module path escapes plugin root or fails alias checks`);
	const safePath = opened.path;
	fs.closeSync(opened.fd);
	if (process.platform === "win32" && params.shouldTryNativeRequire?.(safePath)) try {
		return nodeRequire(safePath);
	} catch {}
	return loadModule(safePath)(safePath);
}
//#endregion
//#region src/channels/plugins/bundled.ts
const log = createSubsystemLogger("channels");
const KAIJIBOT_PACKAGE_ROOT = resolveKaijiBotPackageRootSync({
	argv1: process.argv[1],
	cwd: process.cwd(),
	moduleUrl: import.meta.url.startsWith("file:") ? import.meta.url : void 0
}) ?? (import.meta.url.startsWith("file:") ? path.resolve(fileURLToPath(new URL("../../..", import.meta.url))) : process.cwd());
function resolveChannelPluginModuleEntry(moduleExport) {
	const resolved = moduleExport && typeof moduleExport === "object" && "default" in moduleExport ? moduleExport.default : moduleExport;
	if (!resolved || typeof resolved !== "object") return null;
	const record = resolved;
	if (record.kind !== "bundled-channel-entry") return null;
	if (typeof record.id !== "string" || typeof record.name !== "string" || typeof record.description !== "string" || typeof record.register !== "function" || typeof record.loadChannelPlugin !== "function") return null;
	return record;
}
function resolveChannelSetupModuleEntry(moduleExport) {
	const resolved = moduleExport && typeof moduleExport === "object" && "default" in moduleExport ? moduleExport.default : moduleExport;
	if (!resolved || typeof resolved !== "object") return null;
	const record = resolved;
	if (record.kind !== "bundled-channel-setup-entry") return null;
	if (typeof record.loadSetupPlugin !== "function") return null;
	return record;
}
function resolveBundledChannelBoundaryRoot(params) {
	const distRoot = path.resolve(KAIJIBOT_PACKAGE_ROOT, "dist", "extensions", params.metadata.dirName);
	if (params.modulePath === distRoot || params.modulePath.startsWith(`${distRoot}${path.sep}`)) return distRoot;
	return path.resolve(KAIJIBOT_PACKAGE_ROOT, "extensions", params.metadata.dirName);
}
function resolveGeneratedBundledChannelModulePath(params) {
	if (!params.entry) return null;
	const resolved = resolveBundledChannelGeneratedPath(KAIJIBOT_PACKAGE_ROOT, params.entry, params.metadata.dirName);
	if (resolved) return resolved;
	return null;
}
function loadGeneratedBundledChannelModule(params) {
	const modulePath = resolveGeneratedBundledChannelModulePath(params);
	if (!modulePath) throw new Error(`missing generated module for bundled channel ${params.metadata.manifest.id}`);
	return loadChannelPluginModule({
		modulePath,
		rootDir: resolveBundledChannelBoundaryRoot({
			metadata: params.metadata,
			modulePath
		}),
		boundaryRootDir: resolveBundledChannelBoundaryRoot({
			metadata: params.metadata,
			modulePath
		}),
		shouldTryNativeRequire: (safePath) => safePath.includes(`${path.sep}dist${path.sep}`) && isJavaScriptModulePath(safePath)
	});
}
function loadGeneratedBundledChannelEntries() {
	const entries = [];
	for (const metadata of listBundledChannelPluginMetadata({
		includeChannelConfigs: false,
		includeSyntheticChannelConfigs: false
	})) {
		if ((metadata.manifest.channels?.length ?? 0) === 0) continue;
		try {
			const entry = resolveChannelPluginModuleEntry(loadGeneratedBundledChannelModule({
				metadata,
				entry: metadata.source
			}));
			if (!entry) {
				log.warn(`[channels] bundled channel entry ${metadata.manifest.id} missing bundled-channel-entry contract; skipping`);
				continue;
			}
			const setupEntry = metadata.setupSource ? resolveChannelSetupModuleEntry(loadGeneratedBundledChannelModule({
				metadata,
				entry: metadata.setupSource
			})) : null;
			entries.push({
				id: metadata.manifest.id,
				entry,
				...setupEntry ? { setupEntry } : {}
			});
		} catch (error) {
			const detail = formatErrorMessage(error);
			log.warn(`[channels] failed to load bundled channel ${metadata.manifest.id}: ${detail}`);
		}
	}
	return entries;
}
const EMPTY_BUNDLED_CHANNEL_STATE = {
	entries: [],
	entriesById: /* @__PURE__ */ new Map(),
	setupEntriesById: /* @__PURE__ */ new Map(),
	sortedIds: [],
	pluginsById: /* @__PURE__ */ new Map(),
	setupPluginsById: /* @__PURE__ */ new Map(),
	secretsById: /* @__PURE__ */ new Map(),
	setupSecretsById: /* @__PURE__ */ new Map(),
	runtimeSettersById: /* @__PURE__ */ new Map()
};
let cachedBundledChannelState = null;
let bundledChannelStateLoadInProgress = false;
const pluginLoadInProgressIds = /* @__PURE__ */ new Set();
const setupPluginLoadInProgressIds = /* @__PURE__ */ new Set();
function getBundledChannelState() {
	if (cachedBundledChannelState) return cachedBundledChannelState;
	if (bundledChannelStateLoadInProgress) return EMPTY_BUNDLED_CHANNEL_STATE;
	bundledChannelStateLoadInProgress = true;
	const entries = loadGeneratedBundledChannelEntries();
	const entriesById = /* @__PURE__ */ new Map();
	const setupEntriesById = /* @__PURE__ */ new Map();
	const runtimeSettersById = /* @__PURE__ */ new Map();
	for (const { entry } of entries) {
		if (entriesById.has(entry.id)) throw new Error(`duplicate bundled channel plugin id: ${entry.id}`);
		entriesById.set(entry.id, entry);
		if (entry.setChannelRuntime) runtimeSettersById.set(entry.id, entry.setChannelRuntime);
	}
	for (const { id, setupEntry } of entries) if (setupEntry) setupEntriesById.set(id, setupEntry);
	try {
		cachedBundledChannelState = {
			entries,
			entriesById,
			setupEntriesById,
			sortedIds: [...entriesById.keys()].toSorted((left, right) => left.localeCompare(right)),
			pluginsById: /* @__PURE__ */ new Map(),
			setupPluginsById: /* @__PURE__ */ new Map(),
			secretsById: /* @__PURE__ */ new Map(),
			setupSecretsById: /* @__PURE__ */ new Map(),
			runtimeSettersById
		};
		return cachedBundledChannelState;
	} finally {
		bundledChannelStateLoadInProgress = false;
	}
}
function listBundledChannelPlugins() {
	return getBundledChannelState().sortedIds.flatMap((id) => {
		const plugin = getBundledChannelPlugin(id);
		return plugin ? [plugin] : [];
	});
}
function listBundledChannelSetupPlugins() {
	return getBundledChannelState().sortedIds.flatMap((id) => {
		const plugin = getBundledChannelSetupPlugin(id);
		return plugin ? [plugin] : [];
	});
}
function getBundledChannelPlugin(id) {
	const state = getBundledChannelState();
	const cached = state.pluginsById.get(id);
	if (cached) return cached;
	if (pluginLoadInProgressIds.has(id)) return;
	const entry = state.entriesById.get(id);
	if (!entry) return;
	pluginLoadInProgressIds.add(id);
	try {
		const plugin = entry.loadChannelPlugin();
		state.pluginsById.set(id, plugin);
		return plugin;
	} finally {
		pluginLoadInProgressIds.delete(id);
	}
}
function getBundledChannelSecrets(id) {
	const state = getBundledChannelState();
	if (state.secretsById.has(id)) return state.secretsById.get(id) ?? void 0;
	const entry = state.entriesById.get(id);
	if (!entry) return;
	const secrets = entry.loadChannelSecrets?.() ?? getBundledChannelPlugin(id)?.secrets;
	state.secretsById.set(id, secrets ?? null);
	return secrets;
}
function getBundledChannelSetupPlugin(id) {
	const state = getBundledChannelState();
	const cached = state.setupPluginsById.get(id);
	if (cached) return cached;
	if (setupPluginLoadInProgressIds.has(id)) return;
	const entry = state.setupEntriesById.get(id);
	if (!entry) return;
	setupPluginLoadInProgressIds.add(id);
	try {
		const plugin = entry.loadSetupPlugin();
		state.setupPluginsById.set(id, plugin);
		return plugin;
	} finally {
		setupPluginLoadInProgressIds.delete(id);
	}
}
function getBundledChannelSetupSecrets(id) {
	const state = getBundledChannelState();
	if (state.setupSecretsById.has(id)) return state.setupSecretsById.get(id) ?? void 0;
	const entry = state.setupEntriesById.get(id);
	if (!entry) return;
	const secrets = entry.loadSetupSecrets?.() ?? getBundledChannelSetupPlugin(id)?.secrets;
	state.setupSecretsById.set(id, secrets ?? null);
	return secrets;
}
function setBundledChannelRuntime(id, runtime) {
	const setter = getBundledChannelState().runtimeSettersById.get(id);
	if (!setter) throw new Error(`missing bundled channel runtime setter: ${id}`);
	setter(runtime);
}
//#endregion
export { listBundledChannelPlugins as a, isJavaScriptModulePath as c, getBundledChannelSetupSecrets as i, loadChannelPluginModule as l, getBundledChannelSecrets as n, listBundledChannelSetupPlugins as o, getBundledChannelSetupPlugin as r, setBundledChannelRuntime as s, getBundledChannelPlugin as t, resolveExistingPluginModulePath as u };
