import { basename, dirname, join, relative, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
import { existsSync, readFileSync } from "node:fs";

//#region \0utils:asset
const hereDirname = () => {
	try {
		return dirname(fileURLToPath(import.meta.url));
	} catch {
		return typeof __dirname !== "undefined" ? __dirname : process.cwd();
	}
};
const findDistRoot = (startDir) => {
	let dir = startDir;
	for (let i = 0; i < 12; i++) {
		if (basename(dir) === "dist") return dir;
		const parent = resolve(dir, "..");
		if (parent === dir) break;
		dir = parent;
	}
	return null;
};
const normalizeFrameFile = (file) => {
	if (!file) return null;
	try {
		if (file.startsWith("file://")) return fileURLToPath(file);
	} catch {}
	return file;
};
/**
* Returns the directory of the *caller* module that invoked readAsset.
* Prefers non-virtual frames; falls back to the first real frame.
*/
const getCallerDir = () => {
	const prev = Error.prepareStackTrace;
	try {
		Error.prepareStackTrace = (_, structured) => structured;
		const err = /* @__PURE__ */ new Error();
		Error.captureStackTrace(err, getCallerDir);
		/** @type {import('node:vm').CallSite[]} */
		const frames = err.stack || [];
		const isVirtualPath = (p) => p.includes(`${sep}_virtual${sep}`) || p.includes("/_virtual/");
		for (const frame of frames) {
			const file = normalizeFrameFile(typeof frame.getFileName === "function" ? frame.getFileName() : null);
			if (!file) continue;
			if (file.includes("node:internal") || file.includes(`${sep}internal${sep}modules${sep}`)) continue;
			if (!isVirtualPath(file)) return dirname(file);
		}
		for (const frame of frames) {
			const file = normalizeFrameFile(typeof frame.getFileName === "function" ? frame.getFileName() : null);
			if (file) return dirname(file);
		}
	} catch {} finally {
		Error.prepareStackTrace = prev;
	}
	return hereDirname();
};
/**
* Read an asset copied from src/** to dist/assets/**.
* - './' or '../' is resolved relative to the *caller module's* emitted directory.
* - otherwise, treat as src-relative.
*
* @param {string} relPath - e.g. './PROMPT.md' or 'utils/AI/askDocQuestion/embeddings/<fileKey>.json'
* @param {BufferEncoding} [encoding='utf8']
*/
const readAsset = (relPath, encoding = "utf8") => {
	const here = hereDirname();
	const distRoot = findDistRoot(here) ?? resolve(here, "..", "..", "dist");
	const assetsRoot = join(distRoot, "assets");
	const tried = [];
	/**
	* Transform dist/(esm|cjs)/... and _virtual/ prefix to clean subpath (Windows-safe)
	*/
	const callerSubpath = relative(distRoot, getCallerDir()).split("\\").join("/").replace(/^(?:dist\/)?(?:esm|cjs)\//, "").replace(/^_virtual\//, "");
	if (relPath.startsWith("./") || relPath.startsWith("../")) {
		const fromCallerAbs = resolve(assetsRoot, callerSubpath, relPath);
		tried.push(fromCallerAbs);
		if (existsSync(fromCallerAbs)) return readFileSync(fromCallerAbs, encoding);
	}
	const directPath = join(assetsRoot, relPath);
	tried.push(directPath);
	if (existsSync(directPath)) return readFileSync(directPath, encoding);
	if (callerSubpath) {
		const nested = join(assetsRoot, callerSubpath, relPath);
		tried.push(nested);
		if (existsSync(nested)) return readFileSync(nested, encoding);
	}
	const msg = [
		"readAsset: file not found.",
		"Searched:",
		...tried.map((p) => `- ${p}`)
	].join("\n");
	throw new Error(msg);
};

//#endregion
export { readAsset };