import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { existsSync } from "node:fs";
import { spawn } from "node:child_process";
//#region src/gateway/workspace-ripgrep.ts
init_logger();
const log = createLogger("WorkspaceRipgrep");
function isEnoent(err) {
	return err !== null && typeof err === "object" && err.code === "ENOENT";
}
let cachedRipgrepBin;
/**
* Prefer `@vscode/ripgrep` when its postinstall placed `bin/rg`; otherwise use `rg` on PATH.
* (Bundled path can be ENOENT if postinstall was skipped or the binary was never downloaded.)
*/
async function resolveRipgrepBinary() {
	if (cachedRipgrepBin) return cachedRipgrepBin;
	let bin = "rg";
	try {
		const { rgPath } = await import("@vscode/ripgrep");
		if (typeof rgPath === "string" && rgPath.length > 0 && existsSync(rgPath)) bin = rgPath;
		else if (typeof rgPath === "string" && rgPath.length > 0) log.debug({ rgPath }, "@vscode/ripgrep binary not on disk; will try rg on PATH");
	} catch {}
	cachedRipgrepBin = bin;
	return bin;
}
/** Run ripgrep in a directory (absolute path). Returns empty array if rg fails to start. */
function runRipgrepInDirectory(query, dirAbsPath) {
	return (async () => {
		const rgExecutable = await resolveRipgrepBinary();
		return await new Promise((resolve) => {
			const rg = spawn(rgExecutable, [
				"--json",
				"--smart-case",
				"--max-count",
				"50",
				"--glob",
				"*.md",
				"--glob",
				"*.txt",
				query,
				dirAbsPath
			], { shell: false });
			const results = [];
			let buffer = "";
			rg.stdout.on("data", (data) => {
				buffer += data.toString();
				const lines = buffer.split("\n");
				buffer = lines.pop() ?? "";
				for (const line of lines) {
					if (!line.trim()) continue;
					try {
						const parsed = JSON.parse(line);
						if (parsed.type === "match" && parsed.data) {
							const d = parsed.data;
							const pathText = d.path?.text ?? "";
							const lineContent = d.lines?.text ?? "";
							const lineNumber = d.line_number ?? 0;
							const sm = d.submatches?.[0];
							results.push({
								filePath: pathText,
								lineNumber,
								lineContent: lineContent.trimEnd(),
								matchStart: sm?.start ?? 0,
								matchEnd: sm?.end ?? 0
							});
						}
					} catch {}
				}
			});
			rg.on("close", () => resolve(results));
			rg.on("error", (err) => {
				if (!isEnoent(err)) log.warn({
					err,
					query,
					dir: dirAbsPath,
					rg: rgExecutable
				}, "ripgrep in-directory: spawn failed");
				else log.debug({
					dir: dirAbsPath,
					rg: rgExecutable
				}, "ripgrep not on PATH; skipping in-directory search");
				resolve([]);
			});
		});
	})();
}
/**
* List workspace-relative file paths via ripgrep `--files` (respects .gitignore; fast on large trees).
* Returns POSIX paths relative to `dirAbsPath`.
*/
function runRipgrepListFiles(dirAbsPath) {
	return (async () => {
		const rgExecutable = await resolveRipgrepBinary();
		return await new Promise((resolve) => {
			const rg = spawn(rgExecutable, [
				"--files",
				"--glob",
				"!**/node_modules/**",
				"--glob",
				"!.git/**",
				"."
			], {
				shell: false,
				cwd: dirAbsPath
			});
			const lines = [];
			let buffer = "";
			rg.stdout.on("data", (data) => {
				buffer += data.toString();
				const parts = buffer.split(/\r?\n/);
				buffer = parts.pop() ?? "";
				for (const line of parts) {
					const t = line.trim();
					if (t) lines.push(t.replace(/\\/g, "/"));
				}
			});
			rg.on("close", (code) => {
				const tail = buffer.trim();
				if (tail) lines.push(tail.replace(/\\/g, "/"));
				if (code !== 0 && lines.length === 0) log.debug({
					code,
					cwd: dirAbsPath,
					rg: rgExecutable
				}, "ripgrep --files: non-zero exit, no output (using fs fallback if any)");
				resolve(lines);
			});
			rg.on("error", (err) => {
				if (isEnoent(err)) log.debug({
					cwd: dirAbsPath,
					rg: rgExecutable
				}, "ripgrep binary not found; workspace file search will use fs fallback when needed");
				else log.warn({
					err,
					cwd: dirAbsPath,
					rg: rgExecutable
				}, "ripgrep --files failed to start");
				resolve([]);
			});
		});
	})();
}
//#endregion
export { runRipgrepInDirectory, runRipgrepListFiles };

//# sourceMappingURL=workspace-ripgrep.js.map