import { built_default } from "./config/dist/esm/built.mjs";
import { join } from "node:path";
import { readFileSync } from "node:fs";
import { getAppLogger } from "@intlayer/config";
import simpleGit from "simple-git";

//#region ../chokidar/dist/esm/listGitFiles.mjs
const getGitRootDir = async () => {
	try {
		return (await simpleGit().revparse(["--show-toplevel"])).trim();
	} catch (error) {
		getAppLogger(built_default)(`Error getting git root directory: ${error}`, { level: "error" });
		return null;
	}
};
const listGitFiles = async ({ mode, baseRef = "origin/main", currentRef = "HEAD", absolute = true }) => {
	try {
		const git = simpleGit();
		const diff = /* @__PURE__ */ new Set();
		if (mode.includes("untracked")) (await git.status()).not_added.forEach((f) => diff.add(f));
		if (mode.includes("uncommitted")) (await git.diff(["--name-only", "HEAD"])).split("\n").filter(Boolean).forEach((file) => diff.add(file));
		if (mode.includes("unpushed")) (await git.diff(["--name-only", "@{push}...HEAD"])).split("\n").filter(Boolean).forEach((file) => diff.add(file));
		if (mode.includes("gitDiff")) {
			await git.fetch(baseRef);
			(await git.diff(["--name-only", `${baseRef}...${currentRef}`])).split("\n").filter(Boolean).forEach((file) => diff.add(file));
		}
		if (absolute) {
			const gitRootDir = await getGitRootDir();
			if (!gitRootDir) return [];
			return Array.from(diff).map((file) => join(gitRootDir, file));
		}
		return Array.from(diff);
	} catch (error) {
		console.warn("Failed to get changes list:", error);
	}
};
const listGitLines = async (filePath, { mode, baseRef = "origin/main", currentRef = "HEAD" }) => {
	const git = simpleGit();
	const changedLines = /* @__PURE__ */ new Set();
	/**
	* Extracts line numbers from a diff generated with `--unified=0`.
	* Each hunk header looks like: @@ -<oldStart>,<oldCount> +<newStart>,<newCount> @@
	* We consider both the "+" (new) side for additions and the "-" (old) side for deletions.
	* For deletions, we add the line before and after the deletion point in the current file.
	*/
	const collectLinesFromDiff = (diffOutput) => {
		const hunkRegex = /@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/g;
		let match;
		while ((match = hunkRegex.exec(diffOutput)) !== null) {
			const oldCount = match[2] ? Number(match[2]) : 1;
			const newStart = Number(match[3]);
			const newCount = match[4] ? Number(match[4]) : 1;
			if (newCount > 0) for (let i = 0; i < newCount; i++) changedLines.add(newStart + i);
			if (oldCount > 0 && newCount === 0) {
				if (newStart > 1) changedLines.add(newStart - 1);
				changedLines.add(newStart);
			}
		}
	};
	if (mode.includes("untracked")) {
		if ((await git.status()).not_added.includes(filePath)) try {
			readFileSync(filePath, "utf-8").split("\n").forEach((_, idx) => changedLines.add(idx + 1));
		} catch {}
	}
	if (mode.includes("uncommitted")) collectLinesFromDiff(await git.diff([
		"--unified=0",
		"HEAD",
		"--",
		filePath
	]));
	if (mode.includes("unpushed")) collectLinesFromDiff(await git.diff([
		"--unified=0",
		"@{push}...HEAD",
		"--",
		filePath
	]));
	if (mode.includes("gitDiff")) {
		await git.fetch(baseRef);
		collectLinesFromDiff(await git.diff([
			"--unified=0",
			`${baseRef}...${currentRef}`,
			"--",
			filePath
		]));
	}
	return Array.from(changedLines).sort((a, b) => a - b);
};

//#endregion
export { listGitFiles, listGitLines };
//# sourceMappingURL=listGitFiles.mjs.map