import { randomUUID } from "node:crypto";
import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { spawnSync } from "node:child_process";
//#region src/tui/clipboard-image.ts
const SUPPORTED_IMAGE_MIME_TYPES = [
	"image/png",
	"image/jpeg",
	"image/webp",
	"image/gif"
];
function baseMimeType(mimeType) {
	return mimeType.split(";")[0]?.trim().toLowerCase() ?? mimeType.toLowerCase();
}
function extensionForImageMimeType(mimeType) {
	switch (baseMimeType(mimeType)) {
		case "image/png": return "png";
		case "image/jpeg": return "jpg";
		case "image/webp": return "webp";
		case "image/gif": return "gif";
		default: return null;
	}
}
function runCommand(command, args, options) {
	const result = spawnSync(command, args, {
		timeout: options?.timeoutMs ?? 3e3,
		maxBuffer: options?.maxBufferBytes ?? 50 * 1024 * 1024
	});
	if (result.error || result.status !== 0) return {
		ok: false,
		stdout: Buffer.alloc(0)
	};
	return {
		ok: true,
		stdout: Buffer.isBuffer(result.stdout) ? result.stdout : Buffer.from(result.stdout ?? "", "utf8")
	};
}
function isWaylandSession(env = process.env) {
	return Boolean(env.WAYLAND_DISPLAY) || env.XDG_SESSION_TYPE === "wayland";
}
function selectPreferredImageMimeType(mimeTypes) {
	for (const preferred of SUPPORTED_IMAGE_MIME_TYPES) {
		const match = mimeTypes.find((t) => baseMimeType(t) === preferred);
		if (match) return match;
	}
	return mimeTypes.find((t) => baseMimeType(t).startsWith("image/")) ?? null;
}
function readClipboardImageViaWlPaste() {
	const list = runCommand("wl-paste", ["--list-types"], { timeoutMs: 1e3 });
	if (!list.ok) return null;
	const selectedType = selectPreferredImageMimeType(list.stdout.toString("utf8").split(/\r?\n/).map((t) => t.trim()).filter(Boolean));
	if (!selectedType) return null;
	const data = runCommand("wl-paste", [
		"--type",
		selectedType,
		"--no-newline"
	]);
	if (!data.ok || data.stdout.length === 0) return null;
	return {
		bytes: data.stdout,
		mimeType: baseMimeType(selectedType)
	};
}
function readClipboardImageViaXclip() {
	for (const mimeType of SUPPORTED_IMAGE_MIME_TYPES) {
		const data = runCommand("xclip", [
			"-selection",
			"clipboard",
			"-t",
			mimeType,
			"-o"
		]);
		if (data.ok && data.stdout.length > 0) return {
			bytes: data.stdout,
			mimeType
		};
	}
	return null;
}
function readClipboardImageViaMac() {
	const tmpFile = join(tmpdir(), `xopc-clip-${randomUUID()}.png`);
	const result = runCommand("osascript", ["-e", [
		"try",
		"  set pngData to the clipboard as «class PNGf»",
		`  set fileRef to POSIX file "${tmpFile}"`,
		"  set fileNumber to open for access fileRef with write permission",
		"  write pngData to fileNumber",
		"  close access fileNumber",
		"  return \"ok\"",
		"on error",
		"  return \"empty\"",
		"end try"
	].join("\n")], { timeoutMs: 5e3 });
	if (!result.ok || result.stdout.toString("utf8").trim() !== "ok") {
		try {
			unlinkSync(tmpFile);
		} catch {}
		return null;
	}
	try {
		const bytes = readFileSync(tmpFile);
		if (bytes.length === 0) return null;
		return {
			bytes: new Uint8Array(bytes),
			mimeType: "image/png"
		};
	} finally {
		try {
			unlinkSync(tmpFile);
		} catch {}
	}
}
function readClipboardImageViaPowerShell() {
	const tmpFile = join(tmpdir(), `xopc-clip-${randomUUID()}.png`);
	let psPath = tmpFile;
	if (process.platform !== "win32") {
		const wslpath = runCommand("wslpath", ["-w", tmpFile], { timeoutMs: 1e3 });
		if (!wslpath.ok) return null;
		psPath = wslpath.stdout.toString("utf8").trim();
	}
	const result = runCommand("powershell.exe", [
		"-NoProfile",
		"-Command",
		[
			"Add-Type -AssemblyName System.Windows.Forms",
			"Add-Type -AssemblyName System.Drawing",
			` $path = '${psPath.replaceAll("'", "''")}'`,
			"$img = [System.Windows.Forms.Clipboard]::GetImage()",
			"if ($img) { $img.Save($path, [System.Drawing.Imaging.ImageFormat]::Png); Write-Output \"ok\" } else { Write-Output \"empty\" }"
		].join("; ")
	], { timeoutMs: 5e3 });
	if (!result.ok || result.stdout.toString("utf8").trim() !== "ok") return null;
	try {
		const bytes = readFileSync(tmpFile);
		if (bytes.length === 0) return null;
		return {
			bytes: new Uint8Array(bytes),
			mimeType: "image/png"
		};
	} catch {
		return null;
	} finally {
		try {
			unlinkSync(tmpFile);
		} catch {}
	}
}
/** Read image bytes from the system clipboard when available. */
async function readClipboardImage(options) {
	const platform = options?.platform ?? process.platform;
	const env = options?.env ?? process.env;
	if (platform === "darwin") return readClipboardImageViaMac();
	if (platform === "win32") return readClipboardImageViaPowerShell();
	if (platform === "linux") {
		if (isWaylandSession(env)) return readClipboardImageViaWlPaste() ?? readClipboardImageViaXclip();
		return readClipboardImageViaXclip() ?? readClipboardImageViaWlPaste();
	}
	return null;
}
/** Write clipboard image to a temp file; caller owns cleanup. */
async function saveClipboardImageToTempFile() {
	const image = await readClipboardImage();
	if (!image) return null;
	const ext = extensionForImageMimeType(image.mimeType) ?? "png";
	const filePath = join(tmpdir(), `xopc-clip-${randomUUID()}.${ext}`);
	writeFileSync(filePath, Buffer.from(image.bytes));
	return filePath;
}
//#endregion
export { extensionForImageMimeType, isWaylandSession, readClipboardImage, saveClipboardImageToTempFile };

//# sourceMappingURL=clipboard-image.js.map