import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { init_paths, resolveConfigPath } from "./paths.js";
import { ConfigSchema, init_schema } from "./schema.js";
import { dirname } from "path";
import { existsSync, mkdirSync, promises, readFileSync } from "fs";
import { config } from "dotenv";
//#region src/config/loader.ts
function registerChannelConfigValidator(fn) {
	channelConfigValidator = fn;
}
function assertChannelPluginConfigs(cfg) {
	channelConfigValidator?.(cfg);
}
/**
* Rotate config backups before writing new config.
* Creates a backup chain: xopc.json.bak, xopc.json.bak.1, xopc.json.bak.2, etc.
*/
async function rotateConfigBackups(configPath) {
	if (CONFIG_BACKUP_COUNT <= 1) return;
	const backupBase = `${configPath}.bak`;
	const maxIndex = CONFIG_BACKUP_COUNT - 1;
	try {
		await promises.unlink(`${backupBase}.${maxIndex}`);
	} catch {}
	for (let index = maxIndex - 1; index >= 1; index--) try {
		await promises.rename(`${backupBase}.${index}`, `${backupBase}.${index + 1}`);
	} catch {}
	try {
		await promises.rename(backupBase, `${backupBase}.1`);
	} catch {}
}
/**
* Load configuration from file
* @param configPath Optional custom config path, defaults to XOPC_CONFIG_PATH or ~/.xopc/xopc.json
*/
function loadConfig(configPath) {
	config({ quiet: true });
	const path = configPath || process.env.XOPC_CONFIG_PATH || resolveConfigPath();
	if (existsSync(path)) try {
		const content = readFileSync(path, "utf-8");
		const json = JSON.parse(content);
		const cfg = ConfigSchema.parse(json);
		assertChannelPluginConfigs(cfg);
		return cfg;
	} catch (error) {
		log.error({
			err: error,
			path
		}, `Failed to load config`);
		const cfg = ConfigSchema.parse(void 0);
		assertChannelPluginConfigs(cfg);
		return cfg;
	}
	const cfg = ConfigSchema.parse(void 0);
	assertChannelPluginConfigs(cfg);
	return cfg;
}
/**
* Save configuration to file
* @param config Configuration object to save
* @param configPath Optional custom config path
*/
async function saveConfig(config, configPath) {
	const path = configPath || process.env.XOPC_CONFIG_PATH || resolveConfigPath();
	const dir = dirname(path);
	if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
	const validated = ConfigSchema.parse(config);
	assertChannelPluginConfigs(validated);
	const content = JSON.stringify(validated, null, 2);
	if (existsSync(path)) {
		await rotateConfigBackups(path);
		try {
			await promises.copyFile(path, `${path}.bak`);
		} catch {}
	}
	await writeTextAtomic(path, content);
}
var log, channelConfigValidator, CONFIG_BACKUP_COUNT;
var init_loader = __esmMin((() => {
	init_write_file_atomic();
	init_schema();
	init_paths();
	init_logger();
	log = createLogger("ConfigLoader");
	channelConfigValidator = null;
	CONFIG_BACKUP_COUNT = 10;
}));
//#endregion
init_loader();
export { init_loader, loadConfig, registerChannelConfigValidator, resolveConfigPath, saveConfig };

//# sourceMappingURL=loader.js.map