#!/usr/bin/env node

import { execFileSync } from "node:child_process";
import {
	chmodSync,
	existsSync,
	mkdirSync,
	readFileSync,
	writeFileSync,
} from "node:fs";
import { join } from "node:path";

const MARKER = "# sf-secret-scan";
const PROTECTED_DELETIONS_MARKER = "# sf-protected-deletions";

function git(args) {
	return execFileSync("git", args, {
		encoding: "utf8",
		shell: process.platform === "win32",
	}).trim();
}

const gitDir = git(["rev-parse", "--git-dir"]);
const repoRoot = git(["rev-parse", "--show-toplevel"]);
const hookDir = join(gitDir, "hooks");
const hookFile = join(hookDir, "pre-commit");
const hookCommand = `node "${join(repoRoot, "scripts", "secret-scan.mjs")}"`;
const protectedDeletionsCommand = `node "${join(
	repoRoot,
	"scripts",
	"check-protected-deletions.mjs",
)}" --cached`;

mkdirSync(hookDir, { recursive: true });

if (existsSync(hookFile)) {
	const current = readFileSync(hookFile, "utf8");
	const additions = [];
	if (!current.includes(MARKER)) {
		additions.push(MARKER, hookCommand);
	}
	if (!current.includes(PROTECTED_DELETIONS_MARKER)) {
		additions.push(
			PROTECTED_DELETIONS_MARKER,
			"# Pre-commit hook: block accidental deletion of hand-written extension declarations",
			protectedDeletionsCommand,
		);
	}
	if (additions.length === 0) {
		process.stdout.write("sf pre-commit hooks already installed.\n");
		process.exit(0);
	}

	const next = `${current.replace(/\s*$/, "\n")}${additions.join("\n")}\n`;
	writeFileSync(hookFile, next, "utf8");
	process.stdout.write("sf pre-commit hooks appended to existing hook.\n");
	process.exit(0);
}

const hookBody = [
	"#!/usr/bin/env sh",
	"# sf-secret-scan",
	"# Pre-commit hook: scan staged files for hardcoded secrets",
	hookCommand,
	"",
	"# sf-protected-deletions",
	"# Pre-commit hook: block accidental deletion of hand-written extension declarations",
	protectedDeletionsCommand,
	"",
].join("\n");

writeFileSync(hookFile, hookBody, "utf8");
try {
	chmodSync(hookFile, 0o755);
} catch {
	// Best effort on Windows filesystems that do not honor chmod.
}

process.stdout.write("sf pre-commit hooks installed.\n");
