import { version } from "../core/package.mjs";
import { dirname } from "node:path";
import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";

//#region ../@intlayer/cli/dist/esm/chokidar/dist/esm/utils/runOnce.mjs
const DEFAULT_RUN_ONCE_OPTIONS = { cacheTimeoutMs: 60 * 1e3 };
/**
* Ensures a callback function runs only once within a specified time window across multiple processes.
* Uses a sentinel file to coordinate execution and prevent duplicate work.
*
* @param sentinelFilePath - Path to the sentinel file used for coordination
* @param callback - The function to execute (should be async)
* @param options - The options for the runOnce function
*
* @example
* ```typescript
* await runPrepareIntlayerOnce(
*   '/tmp/intlayer-sentinel',
*   async () => {
*     // Your initialization logic here
*     await prepareIntlayer();
*   },
*   30 * 1000 // 30 seconds cache
* );
* ```
*
* @throws {Error} When there are unexpected filesystem errors
*/
const runOnce = async (sentinelFilePath, callback, options) => {
	const { onIsCached, cacheTimeoutMs, forceRun } = {
		...DEFAULT_RUN_ONCE_OPTIONS,
		...options ?? {}
	};
	const currentTimestamp = Date.now();
	try {
		const sentinelAge = currentTimestamp - (await stat(sentinelFilePath)).mtime.getTime();
		let shouldRebuild = Boolean(forceRun) || sentinelAge > cacheTimeoutMs;
		if (!shouldRebuild) try {
			const raw = await readFile(sentinelFilePath, "utf8");
			let cachedVersion;
			try {
				cachedVersion = JSON.parse(raw).version;
			} catch {
				cachedVersion = void 0;
			}
			if (!cachedVersion || cachedVersion !== version) shouldRebuild = true;
		} catch {
			shouldRebuild = true;
		}
		if (shouldRebuild) try {
			await unlink(sentinelFilePath);
		} catch (err) {
			if (err.code !== "ENOENT") throw err;
		}
		else {
			await onIsCached?.();
			return;
		}
	} catch (err) {
		if (err.code === "ENOENT") {} else throw err;
	}
	try {
		await mkdir(dirname(sentinelFilePath), { recursive: true });
		const data = {
			version,
			timestamp: currentTimestamp
		};
		await writeFile(sentinelFilePath, JSON.stringify(data), { flag: "wx" });
	} catch (err) {
		if (err.code === "EEXIST") return;
		throw err;
	}
	await callback();
};

//#endregion
export { runOnce };
//# sourceMappingURL=runOnce.mjs.map