import { r as extractErrorCode } from "./errors-DtoeWeWg.js";
import { t as resolveGlobalMap } from "./global-singleton-PwlQSEal.js";
import { t as createAsyncLock } from "./async-lock-CaiUOILd.js";
import { r as readRegularFile } from "./regular-file-BD2zl6_l.js";
import { n as replaceFileAtomic } from "./replace-file-BrS02dAb.js";
import "./error-runtime-bA4QMuNf.js";
import "./security-runtime-DXMgUC3f.js";
import "./async-lock-runtime-sEaHdn0J.js";
import { t as replaceManagedMarkdownBlock } from "./memory-host-markdown-mHNl3RAL.js";
import path from "node:path";
import fs from "node:fs/promises";
//#region extensions/memory-core/src/dreaming-dreams-file.ts
const DREAMS_FILENAMES = ["DREAMS.md", "dreams.md"];
const DEEP_START_MARKER = "<!-- openclaw:dreaming:deep:start -->";
const DEEP_END_MARKER = "<!-- openclaw:dreaming:deep:end -->";
const dreamsFileLocks = resolveGlobalMap(Symbol.for("openclaw.memoryCore.dreamingNarrative.fileLocks"));
async function resolveDreamsPath(workspaceDir) {
	for (const name of DREAMS_FILENAMES) {
		const target = path.join(workspaceDir, name);
		try {
			await fs.access(target);
			return target;
		} catch (err) {
			if (err?.code !== "ENOENT") throw err;
		}
	}
	return path.join(workspaceDir, DREAMS_FILENAMES[0]);
}
function isEmptyDreamsReadError(err) {
	const code = extractErrorCode(err);
	if (code === "ENOENT" || code === "ENOTDIR" || code === "not-found" || code === "not-file" || code === "path-alias" || code === "path-mismatch" || code === "symlink") return true;
	return err instanceof Error && err.message === "path must be a regular file";
}
async function readDreamsFile(dreamsPath) {
	try {
		return (await readRegularFile({ filePath: dreamsPath })).buffer.toString("utf-8");
	} catch (err) {
		if (isEmptyDreamsReadError(err)) return "";
		throw err;
	}
}
async function assertSafeDreamsPath(dreamsPath) {
	const stat = await fs.lstat(dreamsPath).catch((err) => {
		if (extractErrorCode(err) === "ENOENT") return null;
		throw err;
	});
	if (!stat) return;
	if (stat.isSymbolicLink()) throw new Error("Refusing to write symlinked DREAMS.md");
	if (!stat.isFile()) throw new Error("Refusing to write non-file DREAMS.md");
}
async function writeDreamsFileAtomic(dreamsPath, content) {
	await assertSafeDreamsPath(dreamsPath);
	await replaceFileAtomic({
		filePath: dreamsPath,
		content,
		mode: 384,
		preserveExistingMode: true,
		tempPrefix: `${path.basename(dreamsPath)}.dreams`,
		throwOnCleanupError: true
	});
}
async function updateDreamsFile(params) {
	const dreamsPath = await resolveDreamsPath(params.workspaceDir);
	await fs.mkdir(path.dirname(dreamsPath), { recursive: true });
	let lockEntry = dreamsFileLocks.get(dreamsPath);
	if (!lockEntry) {
		lockEntry = {
			withLock: createAsyncLock(),
			refs: 0
		};
		dreamsFileLocks.set(dreamsPath, lockEntry);
	}
	lockEntry.refs += 1;
	try {
		return await lockEntry.withLock(async () => {
			const existing = await readDreamsFile(dreamsPath);
			const { content, result, shouldWrite = true } = await params.updater(existing, dreamsPath);
			if (shouldWrite) await writeDreamsFileAtomic(dreamsPath, content.endsWith("\n") ? content : `${content}\n`);
			return result;
		});
	} finally {
		lockEntry.refs -= 1;
		if (lockEntry.refs <= 0 && dreamsFileLocks.get(dreamsPath) === lockEntry) dreamsFileLocks.delete(dreamsPath);
	}
}
async function updateDeepDreamsFile(params) {
	const body = params.bodyLines.length > 0 ? params.bodyLines.join("\n") : "- No durable changes.";
	return await updateDreamsFile({
		workspaceDir: params.workspaceDir,
		updater: (existing, dreamsPath) => ({
			content: replaceManagedMarkdownBlock({
				original: existing,
				heading: "## Deep Sleep",
				startMarker: DEEP_START_MARKER,
				endMarker: DEEP_END_MARKER,
				body
			}),
			result: dreamsPath
		})
	});
}
//#endregion
export { updateDreamsFile as i, resolveDreamsPath as n, updateDeepDreamsFile as r, readDreamsFile as t };
