#!/bin/bash
# Git pre-commit hook for HotPlex Worker
# Fast checks to ensure code health before commit

set -e

# ANSI color codes
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

printf "${YELLOW}🔍 Running pre-commit checks...${NC}\n"

# 0. Block large files and binary blobs (>1MB at repo root)
BLOCKED=""
MAX_SIZE=1048576  # 1MB
STAGED_ALL=$(git diff --cached --name-only --diff-filter=ACM || true)
if [ -n "$STAGED_ALL" ]; then
    while IFS= read -r f; do
        # Skip files under cmd/, examples/, docs/, assets/ (intentional binaries)
        case "$f" in
            cmd/*|examples/*|docs/*|assets/*|webchat/*) continue ;;
        esac
        size=$(git cat-file -s "$(git ls-files -s "$f" | awk '{print $2}')" 2>/dev/null || echo 0)
        if [ "$size" -gt "$MAX_SIZE" ]; then
            BLOCKED="$BLOCKED\n  $f ($(( size / 1048576 ))MB)"
        fi
        # Block known binary patterns at repo root
        case "$f" in
            hotplex|hotplex-*|*.exe|*.dll|*.so|*.dylib)
                if [ "$f" != "hotplex-worker.db" ]; then
                    BLOCKED="$BLOCKED\n  $f (binary pattern blocked)"
                fi
                ;;
        esac
    done <<< "$STAGED_ALL"
fi
if [ -n "$BLOCKED" ]; then
    printf "${RED}❌ Blocked: large/binary files detected:${NC}\n"
    printf "$BLOCKED\n"
    printf "${YELLOW}Add to .gitignore or move to bin/ directory.${NC}\n"
    exit 1
fi

STAGED_GO_FILES=$(echo "$STAGED_ALL" | grep ".go$" || true)

if [ -z "$STAGED_GO_FILES" ]; then
    printf "${GREEN}✅ No Go files staged, skipping checks.${NC}\n"
    exit 0
fi

# 1. Format Check (gofmt)
printf "🔹 Checking code formatting (gofmt)...\n"
DIFF=$(gofmt -d $STAGED_GO_FILES)
if [ -n "$DIFF" ]; then
    printf "${YELLOW}⚠️  Staged code is not formatted correctly. Please run 'make fmt':${NC}\n"
    echo "$STAGED_GO_FILES"
    exit 1
fi

# 2. Dependency Check (go mod tidy)
if git diff --cached --name-only | grep -E "go.mod|go.sum" > /dev/null; then
    printf "🔹 Verifying dependencies (go mod tidy)...\n"
    go mod tidy
    if ! git diff --exit-code go.mod go.sum > /dev/null; then
        printf "${YELLOW}⚠️  go.mod or go.sum are out of sync. Run 'make tidy' and stage changes.${NC}\n"
        exit 1
    fi
fi

# 3. Lint (golangci-lint on staged packages only)
if command -v golangci-lint &> /dev/null; then
    printf "🔹 Running linter (golangci-lint)...\n"
    # Separate main-module files from client/ submodule (separate go.mod)
    MAIN_FILES=$(echo "$STAGED_GO_FILES" | grep -v '^client/' || true)
    CLIENT_FILES=$(echo "$STAGED_GO_FILES" | grep '^client/' || true)

    # Lint main module packages
    if [ -n "$MAIN_FILES" ]; then
        if ! echo "$MAIN_FILES" | xargs dirname | sort -u | xargs golangci-lint run 2>&1; then
            printf "${YELLOW}⚠️  Linter found issues. Fix before committing.${NC}\n"
            exit 1
        fi
    fi

    # Lint client submodule (run from client/ with its own go.mod)
    if [ -n "$CLIENT_FILES" ]; then
        if ! echo "$CLIENT_FILES" | sed 's|^client/||' | xargs dirname | sort -u | xargs -I{} sh -c 'cd client && golangci-lint run ./{} 2>&1'; then
            printf "${YELLOW}⚠️  Linter found issues in client/. Fix before committing.${NC}\n"
            exit 1
        fi
    fi
else
    printf "${YELLOW}⚠️  golangci-lint not found, skipping.${NC}\n"
fi

printf "${GREEN}✅ Pre-commit checks passed!${NC}\n"
exit 0
