#!/bin/sh
# Pre-commit hook: run CI-equivalent checks on staged files.
# Fails the commit if any check fails — matches CI pipeline in .gitea/workflows/ci.yaml.
#
# To skip: git commit --no-verify

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Colour

FAILED=0

# ---------- Frontend (prettier --write, then eslint) ----------
FRONTEND_STAGED=$(git diff --cached --name-only -- 'frontend/' | head -1)
if [ -n "$FRONTEND_STAGED" ]; then
	printf "${YELLOW}Auto-formatting staged frontend files with prettier...${NC}\n"
	cd frontend && npx prettier --write . 2>&1
	# Re-stage any files prettier modified so formatting is included in the commit
	cd ..
	git diff --name-only -- 'frontend/' | xargs -r git add
fi

# Always run eslint — catches pre-existing issues that would fail the pipeline
printf "${YELLOW}Checking eslint (all files)...${NC}\n"
if ! cd frontend && npx eslint . 2>&1; then
	printf "${RED}✖ eslint failed${NC}\n"
	FAILED=1
fi
cd ..

# ---------- Backend checks (only if backend/ files changed) ----------
BACKEND_FILES=$(git diff --cached --name-only -- 'backend/' | head -1)
if [ -n "$BACKEND_FILES" ]; then
	printf "${YELLOW}Checking go vet...${NC}\n"
	if ! cd backend && go vet -tags "test,dev" ./... 2>&1; then
		printf "${RED}✖ go vet failed${NC}\n"
		FAILED=1
	fi
	cd ..

	printf "${YELLOW}Checking golangci-lint...${NC}\n"
	if ! cd backend && golangci-lint run ./... --timeout 3m 2>&1; then
		printf "${RED}✖ golangci-lint failed${NC}\n"
		FAILED=1
	fi
	cd ..

	printf "${YELLOW}Checking staticcheck...${NC}\n"
	if ! cd backend && staticcheck -tags "test,dev" ./... 2>&1; then
		printf "${RED}✖ staticcheck failed${NC}\n"
		FAILED=1
	fi
	cd ..

	printf "${YELLOW}Checking gosec...${NC}\n"
	if ! cd backend && gosec -severity medium -tags "test,dev" ./... 2>&1; then
		printf "${RED}✖ gosec failed${NC}\n"
		FAILED=1
	fi
	cd ..

	printf "${YELLOW}Checking go mod tidy...${NC}\n"
	cp backend/go.sum backend/go.sum.bak
	cp backend/go.mod backend/go.mod.bak
	cd backend && go mod tidy && cd ..
	if ! diff -q backend/go.sum backend/go.sum.bak >/dev/null 2>&1 || ! diff -q backend/go.mod backend/go.mod.bak >/dev/null 2>&1; then
		printf "${RED}✖ go.mod or go.sum out of date — run 'go mod tidy' and stage the changes${NC}\n"
		FAILED=1
	fi
	rm -f backend/go.sum.bak backend/go.mod.bak
fi

# ---------- Global checks ----------

printf "${YELLOW}Checking secrets...${NC}\n"
if command -v gitleaks >/dev/null 2>&1; then
	if ! gitleaks detect --source . --no-banner 2>&1; then
		printf "${RED}✖ gitleaks detected secrets${NC}\n"
		FAILED=1
	fi
else
	printf "  (gitleaks not installed — skipping; CI will catch secrets)\n"
fi

# ---------- Result ----------
if [ "$FAILED" -ne 0 ]; then
	printf "\n${RED}Commit blocked — fix the issues above, then commit again.${NC}\n"
	printf "${YELLOW}To skip checks: git commit --no-verify${NC}\n"
	exit 1
fi

printf "${GREEN}✓ All pre-commit checks passed${NC}\n"
exit 0
