import { checkFileSafety } from "../../../../src/agent/prompt/safety.js";
import { getMimeType } from "../../../../src/channels/media.js";
import { getWorkspacePath } from "../../../../src/config/workspace-path-helpers.js";
import { promises } from "node:fs";
import path from "node:path";
import { Readable } from "node:stream";
//#region extensions/feishu/src/outbound/media-load.ts
function isPathUnderRoots(resolved, roots) {
	const norm = path.normalize(resolved);
	for (const root of roots) {
		const r = path.normalize(root);
		if (norm === r || norm.startsWith(r + path.sep)) return true;
	}
	return false;
}
async function loadMediaForFeishu(cfg, rawInput, opts) {
	const input = rawInput.trim().startsWith("@") ? rawInput.trim().slice(1).trim() : rawInput.trim();
	if (!input) throw new Error("empty media reference");
	const isHttpUrl = /^https?:\/\//i.test(input);
	const isFileUrl = /^file:\/\//i.test(input);
	const isDataUrl = /^data:/i.test(input);
	if (isHttpUrl) {
		const res = await fetch(input, { redirect: "follow" });
		if (!res.ok) throw new Error(`Failed to fetch media: HTTP ${res.status}`);
		const buf = Buffer.from(await res.arrayBuffer());
		if (buf.length > opts.maxBytes) throw new Error(`Media too large (${buf.length} bytes, max ${opts.maxBytes})`);
		return {
			buffer: buf,
			mimeType: (res.headers.get("content-type") || "application/octet-stream").split(";")[0]?.trim() || "application/octet-stream",
			filename: safeBasename(new URL(input).pathname) || "media.bin",
			stream: Readable.from(buf)
		};
	}
	if (isDataUrl) {
		const m = /^data:([^;,]+)?(;base64)?,/i.exec(input);
		if (!m) throw new Error("Invalid data URL");
		const mime = (m[1] || "application/octet-stream").trim();
		const isB64 = Boolean(m[2]);
		const dataPart = input.slice(m[0].length);
		const buf = isB64 ? Buffer.from(dataPart, "base64") : Buffer.from(decodeURIComponent(dataPart), "utf8");
		if (buf.length > opts.maxBytes) throw new Error(`Media too large (${buf.length} bytes, max ${opts.maxBytes})`);
		return {
			buffer: buf,
			mimeType: mime,
			filename: mime.startsWith("image/") ? `image.${mime.split("/")[1] || "bin"}` : "media.bin",
			stream: Readable.from(buf)
		};
	}
	const b64Candidate = input.replace(/^['"]|['"]$/g, "");
	if (b64Candidate.length >= 256 && b64Candidate.length % 4 === 0 && /^[A-Za-z0-9+/=\r\n]+$/.test(b64Candidate) && !b64Candidate.includes(path.sep)) {
		const buf = Buffer.from(b64Candidate, "base64");
		if (buf.length > 0) {
			if (buf.length > opts.maxBytes) throw new Error(`Media too large (${buf.length} bytes, max ${opts.maxBytes})`);
			const { mimeType, filename } = sniffBufferType(buf);
			return {
				buffer: buf,
				mimeType,
				filename,
				stream: Readable.from(buf)
			};
		}
	}
	let filePath = input;
	if (isFileUrl) filePath = input.slice(7);
	if (!path.isAbsolute(filePath)) filePath = path.resolve(getWorkspacePath(cfg), filePath);
	filePath = path.normalize(filePath);
	const safety = checkFileSafety("read", filePath);
	if (!safety.allowed) throw new Error(safety.message ?? "File path not allowed");
	const workspace = getWorkspacePath(cfg);
	const roots = [workspace, ...opts.localRoots ?? []].filter(Boolean);
	const realPath = await promises.realpath(filePath).catch(() => filePath);
	if (!isPathUnderRoots(realPath, [await promises.realpath(workspace).catch(() => workspace), ...await Promise.all(roots.map((r) => promises.realpath(r).catch(() => r)))])) throw new Error(`Path not under workspace or allowed roots: ${filePath}`);
	const st = await promises.stat(realPath).catch((err) => {
		const em = err instanceof Error ? err.message : String(err);
		throw new Error(`Media file not found or unreadable: ${filePath} (resolved: ${realPath}). ${em}`);
	});
	if (!st.isFile()) throw new Error(`Not a file: ${filePath}`);
	if (st.size > opts.maxBytes) throw new Error(`Media too large (${st.size} bytes, max ${opts.maxBytes})`);
	const buffer = await promises.readFile(realPath);
	const filename = path.basename(realPath) || "media.bin";
	return {
		buffer,
		mimeType: getMimeType("document", realPath),
		filename,
		stream: Readable.from(buffer)
	};
}
function sniffBufferType(buf) {
	if (buf.length >= 8 && buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71 && buf[4] === 13 && buf[5] === 10 && buf[6] === 26 && buf[7] === 10) return {
		mimeType: "image/png",
		filename: "image.png"
	};
	if (buf.length >= 3 && buf[0] === 255 && buf[1] === 216 && buf[2] === 255) return {
		mimeType: "image/jpeg",
		filename: "image.jpg"
	};
	if (buf.length >= 6 && buf.subarray(0, 6).toString("ascii") === "GIF89a") return {
		mimeType: "image/gif",
		filename: "image.gif"
	};
	if (buf.length >= 12 && buf.subarray(0, 4).toString("ascii") === "RIFF" && buf.subarray(8, 12).toString("ascii") === "WEBP") return {
		mimeType: "image/webp",
		filename: "image.webp"
	};
	if (buf.length >= 4 && buf.subarray(0, 4).toString("ascii") === "%PDF") return {
		mimeType: "application/pdf",
		filename: "file.pdf"
	};
	return {
		mimeType: "application/octet-stream",
		filename: "media.bin"
	};
}
function safeBasename(p) {
	try {
		return path.basename(p).replace(/[\\/:*?"<>|]/g, "_");
	} catch {
		return "";
	}
}
//#endregion
export { loadMediaForFeishu };

//# sourceMappingURL=media-load.js.map