import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { randomUUID } from "node:crypto";
import { chmodSync, closeSync, copyFileSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync } from "node:fs";
import { chmod, copyFile, mkdir, open, rename, rm } from "node:fs/promises";
import path from "node:path";
//#region src/infra/write-file-atomic.ts
/**
* Durable single-file writes: temp file → fsync → rename to target.
* Avoids torn JSON when the process dies mid-write.
*/
function errno(err) {
	return err instanceof Error ? err.code : void 0;
}
function replaceTempWithTargetSync(tempPath, filePath, mode) {
	try {
		renameSync(tempPath, filePath);
		return;
	} catch (err) {
		const code = errno(err);
		if (process.platform !== "win32" || code !== "EPERM" && code !== "EEXIST") throw err;
	}
	copyFileSync(tempPath, filePath);
	try {
		chmodSync(filePath, mode);
	} catch {}
	rmSync(tempPath, { force: true });
}
async function replaceTempWithTarget(tempPath, filePath, mode) {
	try {
		await rename(tempPath, filePath);
		return;
	} catch (err) {
		const code = errno(err);
		if (process.platform !== "win32" || code !== "EPERM" && code !== "EEXIST") throw err;
	}
	await copyFile(tempPath, filePath);
	try {
		await chmod(filePath, mode);
	} catch {}
	await rm(tempPath, { force: true }).catch(() => void 0);
}
/**
* Write UTF-8 text atomically. Creates parent directories when missing.
*/
async function writeTextAtomic(filePath, content, options) {
	const mode = options?.mode ?? 384;
	const dir = path.dirname(filePath);
	const mkdirOpts = { recursive: true };
	if (typeof options?.ensureDirMode === "number") mkdirOpts.mode = options.ensureDirMode;
	await mkdir(dir, mkdirOpts);
	const tmp = `${filePath}.${randomUUID()}.tmp`;
	try {
		const handle = await open(tmp, "w", mode);
		try {
			await handle.writeFile(content, { encoding: "utf8" });
			await handle.sync();
		} finally {
			await handle.close().catch(() => void 0);
		}
		try {
			await chmod(tmp, mode);
		} catch {}
		await replaceTempWithTarget(tmp, filePath, mode);
		try {
			await chmod(filePath, mode);
		} catch {}
	} finally {
		await rm(tmp, { force: true }).catch(() => void 0);
	}
	try {
		const dirHandle = await open(dir, "r");
		try {
			await dirHandle.sync();
		} finally {
			await dirHandle.close().catch(() => void 0);
		}
	} catch {}
}
/**
* Synchronous atomic UTF-8 write (temp → fsync → rename). For CLI / sync stores.
*/
function writeTextAtomicSync(filePath, content, options) {
	const mode = options?.mode ?? 384;
	const dir = path.dirname(filePath);
	const mkdirOpts = { recursive: true };
	if (typeof options?.ensureDirMode === "number") mkdirOpts.mode = options.ensureDirMode;
	mkdirSync(dir, mkdirOpts);
	const tmp = `${filePath}.${randomUUID()}.tmp`;
	try {
		writeFileSync(tmp, content, { encoding: "utf8" });
		const fd = openSync(tmp, "r+");
		try {
			fsyncSync(fd);
		} finally {
			closeSync(fd);
		}
		try {
			chmodSync(tmp, mode);
		} catch {}
		replaceTempWithTargetSync(tmp, filePath, mode);
		try {
			chmodSync(filePath, mode);
		} catch {}
	} finally {
		try {
			rmSync(tmp, { force: true });
		} catch {}
	}
}
var init_write_file_atomic = __esmMin((() => {}));
//#endregion
init_write_file_atomic();
export { init_write_file_atomic, writeTextAtomic, writeTextAtomicSync };

//# sourceMappingURL=write-file-atomic.js.map