#!/bin/bash
#
# Pre-commit hook that runs linting/formatting on staged files only
#
set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}Running pre-commit checks...${NC}"

# Get list of staged files
STAGED_FILES=$(git diff --cached --name-only)

if [[ -z "$STAGED_FILES" ]]; then
    echo -e "${YELLOW}No staged files found. Skipping pre-commit checks.${NC}"
    exit 0
fi

echo "Staged files:"
echo "$STAGED_FILES" | sed 's/^/  /'
echo

# Get repo root
REPO_ROOT=$(git rev-parse --show-toplevel)

# Collect files by type
RUST_FILES=()
CAIRO_FILES=()
PRETTIER_FILES=()

while IFS= read -r file; do
    # Skip deleted files (they don't exist on filesystem)
    if [[ ! -f "$file" ]]; then
        continue
    fi
    
    if [[ "$file" =~ \.rs$ ]] || [[ "$file" =~ ^Cargo\.(toml|lock)$ ]] || [[ "$file" =~ ^rust-toolchain\.toml$ ]]; then
        if [[ "$file" =~ \.rs$ ]]; then
            RUST_FILES+=("$file")
        fi
    elif [[ "$file" =~ ^contracts/.*\.cairo$ ]] || [[ "$file" =~ ^contracts/Scarb\.(toml|lock)$ ]]; then
        if [[ "$file" =~ \.cairo$ ]]; then
            CAIRO_FILES+=("$file")
        fi
    elif [[ "$file" =~ \.(md|yaml|yml)$ ]] && [[ ! "$file" =~ CLAUDE\.md ]]; then
        PRETTIER_FILES+=("$file")
    fi
done <<<"$STAGED_FILES"

# Track errors
ERRORS=0

# Run checks using the main lint script
if [[ ${#RUST_FILES[@]} -gt 0 ]] || echo "$STAGED_FILES" | grep -qE '^Cargo\.(toml|lock)$|^rust-toolchain\.toml$'; then
    echo -e "${BLUE}Running Rust checks...${NC}"
    if [[ ${#RUST_FILES[@]} -gt 0 ]]; then
        if ! "$REPO_ROOT/bin/lint" --rust --files "${RUST_FILES[@]}"; then
            ((ERRORS++))
        fi
    else
        if ! "$REPO_ROOT/bin/lint" --rust; then
            ((ERRORS++))
        fi
    fi
    echo
fi

if [[ ${#CAIRO_FILES[@]} -gt 0 ]] || echo "$STAGED_FILES" | grep -qE '^contracts/Scarb\.(toml|lock)$'; then
    echo -e "${BLUE}Running Cairo checks...${NC}"
    if [[ ${#CAIRO_FILES[@]} -gt 0 ]]; then
        if ! "$REPO_ROOT/bin/lint" --cairo --files "${CAIRO_FILES[@]}"; then
            ((ERRORS++))
        fi
    else
        if ! "$REPO_ROOT/bin/lint" --cairo; then
            ((ERRORS++))
        fi
    fi
    echo
fi

if [[ ${#PRETTIER_FILES[@]} -gt 0 ]]; then
    echo -e "${BLUE}Running Prettier checks...${NC}"
    if ! "$REPO_ROOT/bin/lint" --prettier --files "${PRETTIER_FILES[@]}"; then
        ((ERRORS++))
    fi
    echo
fi

# Check if any files were modified after formatting
MODIFIED_FILES=()
if [[ ${#RUST_FILES[@]} -gt 0 ]]; then
    for file in "${RUST_FILES[@]}"; do
        if [ -f "$file" ] && ! git diff --name-only --exit-code "$file" >/dev/null 2>&1; then
            MODIFIED_FILES+=("$file")
        fi
    done
fi
if [[ ${#CAIRO_FILES[@]} -gt 0 ]]; then
    for file in "${CAIRO_FILES[@]}"; do
        if [ -f "$file" ] && ! git diff --name-only --exit-code "$file" >/dev/null 2>&1; then
            MODIFIED_FILES+=("$file")
        fi
    done
fi
if [[ ${#PRETTIER_FILES[@]} -gt 0 ]]; then
    for file in "${PRETTIER_FILES[@]}"; do
        if [ -f "$file" ] && ! git diff --name-only --exit-code "$file" >/dev/null 2>&1; then
            MODIFIED_FILES+=("$file")
        fi
    done
fi

if [ ${#MODIFIED_FILES[@]} -gt 0 ]; then
    echo -e "${YELLOW}📝 The following files were formatted:${NC}"
    printf '  %s\n' "${MODIFIED_FILES[@]}"
    echo -e "${YELLOW}Please stage these changes and commit again.${NC}"
    exit 1
fi

# Summary
if [[ $ERRORS -eq 0 ]]; then
    echo -e "${GREEN}✅ All pre-commit checks passed!${NC}"
    exit 0
else
    echo -e "${RED}❌ Pre-commit checks failed with $ERRORS error(s)${NC}"
    echo -e "${YELLOW}Fix the issues above and try committing again.${NC}"
    exit 1
fi
