import { existsSync } from "node:fs";
import { dirname, join, relative } from "node:path";

const PUSH_WRAPPER_CANDIDATES = [
	join("scripts", "ace_safe_push.sh"),
	join("scripts", "safe_push.sh"),
	join("scripts", "safe-push.sh"),
	"justfile",
];
/**
 * Detect the version-control system for the current repository.
 *
 * Purpose: keep repo-specific VCS policy local to the current checkout so a JJ
 * rule from one project is never applied to an unrelated Git repository.
 *
 * Consumer: system-context.ts when injecting durable SF operating guidance.
 */
export function detectRepositoryVcsContext(startDir) {
	let current = startDir;
	while (true) {
		const jjDir = join(current, ".jj");
		const gitMarker = join(current, ".git");
		if (existsSync(jjDir)) {
			return {
				kind: "jj",
				root: current,
				pushWrapper: findRepoPushWrapper(current),
			};
		}
		if (existsSync(gitMarker)) {
			return {
				kind: "git",
				root: current,
				pushWrapper: findRepoPushWrapper(current),
			};
		}
		const parent = dirname(current);
		if (parent === current) {
			return { kind: "none", root: null, pushWrapper: null };
		}
		current = parent;
	}
}
/**
 * Format repo-local VCS guidance for the system prompt.
 *
 * Purpose: make push/commit behavior conditional on the current repository
 * instead of global agent memory or nearby checkout conventions.
 *
 * Consumer: system-context.ts before agent start.
 */
export function buildRepositoryVcsContextBlock(startDir) {
	const context = detectRepositoryVcsContext(startDir);
	if (context.kind === "none" || !context.root) return "";
	const lines = [
		"",
		"",
		"[REPOSITORY VCS CONTEXT]",
		`Repository root: ${context.root}`,
		`Detected VCS: ${context.kind === "jj" ? "Jujutsu (JJ)" : "Git"}`,
		"",
		"Repo-local rules:",
		"- Detect the current repository before choosing commit or push commands.",
		"- Follow this repository's own instructions, hooks, and wrapper scripts.",
		"- Do not apply push rules from sibling or unrelated repositories.",
		"- Treat JJ as a repo-specific skill: use it only when this repository is JJ-backed.",
	];
	if (context.pushWrapper) {
		lines.push(
			`- Repo-owned push wrapper detected: ${relative(context.root, context.pushWrapper)}`,
			"- Prefer the repo-owned wrapper for pushes unless the user explicitly says otherwise.",
		);
	} else if (context.kind === "git") {
		lines.push(
			"- No repo-owned push wrapper was detected; normal Git commands are appropriate for this repository.",
		);
	} else {
		lines.push(
			"- No repo-owned JJ push wrapper was detected; inspect repo docs before pushing.",
		);
	}
	return lines.join("\n");
}
function findRepoPushWrapper(root) {
	for (const candidate of PUSH_WRAPPER_CANDIDATES) {
		const path = join(root, candidate);
		if (existsSync(path)) return path;
	}
	return null;
}
