#!/bin/bash

# --- JAVA VERSION CHECK ---
REQUIRED_JAVA_MAJOR=21
JAVA_VERSION_OUTPUT=$(java -version 2>&1 | head -n 1)
JAVA_MAJOR=$(echo "$JAVA_VERSION_OUTPUT" | sed -E 's/.*version "([0-9]+)\..*/\1/')
if [ "$JAVA_MAJOR" != "$REQUIRED_JAVA_MAJOR" ]; then
    echo -e "\033[0;31m❌ ERROR: Java $REQUIRED_JAVA_MAJOR is required to build this project.\033[0m"
    echo -e "  Detected: $JAVA_VERSION_OUTPUT"
    echo -e "  JAVA_HOME: $JAVA_HOME"
    echo -e "  Which java: $(which java)"
    echo -e "\033[1;33mPlease switch to JDK $REQUIRED_JAVA_MAJOR before committing.\033[0m"
    echo -e "  - Or set JAVA_HOME to a JDK $REQUIRED_JAVA_MAJOR installation."
    echo -e "  - On CI/F-Droid, ensure the build environment uses JDK $REQUIRED_JAVA_MAJOR."
    echo -e "\033[1;33mCommit blocked.\033[0m"
    exit 1
fi

# --- START DIAGNOSTICS ---
echo "--- Pre-commit Hook Environment Diagnostics ---"
echo "Running from: $(pwd)"
echo "User: $(whoami)"
echo "PATH: $PATH"
echo "JAVA_HOME: $JAVA_HOME"
echo "Java Version:"
java -version
echo "Which Java: $(which java)"
echo "-------------------------------------------"
# --- END DIAGNOSTICS ---

#
# Code Quality pre-commit hook - Enhanced version
# This hook ensures code quality by checking formatting and license headers
#
# Installation:

#   Run once from repository root: ./.githooks/setup.sh
#   This configures git to use .githooks directory for all hooks
#
# Workflow:
# 1. Run ktlintCheck on staged files
# 2. Run spotlessCheck for license headers
# 3. If issues found -> auto-format and re-check
# 4. If any non-auto-correctable issues -> fail with clear feedback
# 5. Block commit only if formatting cannot fix all issues
#
# Features:
# - Checks both code style (ktlint) and license headers (spotless)
# - Only processes files that are staged for commit
# - Temporarily stashes unstaged changes to avoid modifying them
# - Automatically re-stages formatted files
# - Fast-fails on non-auto-correctable issues
# - Provides clear, color-coded console feedback
#

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

cd "$REPO_ROOT"

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

echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}Running code quality checks on staged files...${NC}"
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"

# Get list of staged Kotlin files
STAGED_KOTLIN_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.kt$' || true)

if [ -z "$STAGED_KOTLIN_FILES" ]; then
    echo ""
    echo -e "${GREEN}✅ No Kotlin files staged for commit${NC}"
    echo -e "${GREEN}✅ Commit proceeding...${NC}"
    exit 0
fi

echo ""
echo -e "${BLUE}Staged Kotlin files:${NC}"
echo "$STAGED_KOTLIN_FILES" | sed 's/^/  • /'
echo ""

# Check if there are any unstaged changes
UNSTAGED_CHANGES=$(git diff --name-only)

if [ -n "$UNSTAGED_CHANGES" ]; then
    echo -e "${BLUE}Temporarily stashing unstaged changes...${NC}"
    git stash push --keep-index --quiet --message "pre-commit-hook-temp-stash"
    STASHED=1
else
    STASHED=0
fi

# Function to restore stash if needed
restore_stash() {
    if [ $STASHED -eq 1 ]; then
        echo -e "${BLUE}Restoring unstaged changes...${NC}"
        git stash pop --quiet
    fi
}

# Step 1: Run ktlintCheck to see current state
echo -e "${BLUE}Step 1: Checking code style (ktlint)...${NC}"
./gradlew ktlintCheck --daemon > /tmp/ktlint_check.log 2>&1
KTLINT_EXIT_CODE=$?

# Step 2: Run spotlessCheck for license headers
echo -e "${BLUE}Step 2: Checking license headers (spotless)...${NC}"
./gradlew spotlessCheck --daemon > /tmp/spotless_check.log 2>&1
SPOTLESS_EXIT_CODE=$?

if [ $KTLINT_EXIT_CODE -eq 0 ] && [ $SPOTLESS_EXIT_CODE -eq 0 ]; then
    # All good! Code is properly formatted with headers
    echo ""
    echo -e "${GREEN}✅ Code style check passed${NC}"
    echo -e "${GREEN}✅ License headers check passed${NC}"
    echo -e "${GREEN}✅ Commit proceeding...${NC}"
    restore_stash
    exit 0
fi

# Step 3: Analyze the failures
echo ""
if [ $KTLINT_EXIT_CODE -ne 0 ] && [ $SPOTLESS_EXIT_CODE -ne 0 ]; then
    echo -e "${YELLOW}Code style and license header issues found. Analyzing...${NC}"
elif [ $KTLINT_EXIT_CODE -ne 0 ]; then
    echo -e "${YELLOW}Code style issues found. Analyzing...${NC}"
else
    echo -e "${YELLOW}License header issues found. Will auto-fix...${NC}"
fi

# Check if there are non-auto-correctable issues
# Ktlint reports these with "(cannot be auto-corrected)"
NON_AUTO_CORRECTABLE=$(grep -c "cannot be auto-corrected" /tmp/ktlint_check.log || true)

if [ "$NON_AUTO_CORRECTABLE" -gt 0 ]; then
    # There are issues that cannot be auto-fixed - fail immediately
    echo ""
    echo -e "${RED}❌ Found $NON_AUTO_CORRECTABLE issue(s) that cannot be auto-corrected!${NC}"
    echo ""
    echo -e "${RED}Non-auto-correctable issues:${NC}"
    grep "cannot be auto-corrected" /tmp/ktlint_check.log | sed 's/^/  /'
    echo ""
    echo -e "${YELLOW}These issues must be fixed manually before committing.${NC}"
    echo ""
    echo -e "${YELLOW}Common fixes:${NC}"
    echo -e "${YELLOW}  • File naming: Add @file:Suppress(\"MatchingDeclarationName\") if temporary${NC}"
    echo -e "${YELLOW}  • Or rename the file to match the class name${NC}"
    echo ""
    echo -e "${YELLOW}After fixing issues:${NC}"
    echo -e "${YELLOW}  1. Stage your changes: git add <files>${NC}"
    echo -e "${YELLOW}  2. Try committing again${NC}"
    echo ""
    echo -e "${YELLOW}To bypass this check (not recommended):${NC}"
    echo -e "${YELLOW}  git commit --no-verify${NC}"
    restore_stash
    exit 1
fi

# Step 4: All issues are auto-correctable, so format the code
echo ""
echo -e "${YELLOW}Running auto-formatters...${NC}"

if [ $KTLINT_EXIT_CODE -ne 0 ]; then
    echo -e "${BLUE}  • Running ktlintFormat...${NC}"
    ./gradlew ktlintFormat --daemon
    KTLINT_FORMAT_EXIT=$?
    if [ $KTLINT_FORMAT_EXIT -ne 0 ]; then
        echo ""
        echo -e "${RED}❌ ktlint formatting failed! Commit blocked.${NC}"
        echo -e "${YELLOW}Review the errors and fix them manually.${NC}"
        restore_stash
        exit 1
    fi
fi

if [ $SPOTLESS_EXIT_CODE -ne 0 ]; then
    echo -e "${BLUE}  • Running spotlessApply (license headers)...${NC}"
    ./gradlew spotlessApply --daemon
    SPOTLESS_APPLY_EXIT=$?
    if [ $SPOTLESS_APPLY_EXIT -ne 0 ]; then
        echo ""
        echo -e "${RED}❌ Spotless formatting failed! Commit blocked.${NC}"
        echo -e "${YELLOW}Review the errors and fix them manually.${NC}"
        restore_stash
        exit 1
    fi
fi

# Step 5: Verify that formatting fixed all issues
echo ""
echo -e "${BLUE}Step 3: Verifying all checks now pass...${NC}"

./gradlew ktlintCheck --daemon > /tmp/ktlint_recheck.log 2>&1
KTLINT_RECHECK=$?

./gradlew spotlessCheck --daemon > /tmp/spotless_recheck.log 2>&1
SPOTLESS_RECHECK=$?

if [ $KTLINT_RECHECK -ne 0 ] || [ $SPOTLESS_RECHECK -ne 0 ]; then
    # This shouldn't happen, but if it does, fail clearly
    echo ""
    echo -e "${RED}❌ Auto-formatting did not fix all issues! Commit blocked.${NC}"
    echo ""
    if [ $KTLINT_RECHECK -ne 0 ]; then
        echo -e "${RED}Remaining ktlint issues:${NC}"
        cat /tmp/ktlint_recheck.log
        echo ""
    fi
    if [ $SPOTLESS_RECHECK -ne 0 ]; then
        echo -e "${RED}Remaining spotless issues:${NC}"
        cat /tmp/spotless_recheck.log
        echo ""
    fi
    echo -e "${YELLOW}This is unexpected. Please review the errors above.${NC}"
    restore_stash
    exit 1
fi

# Step 5: Re-stage formatted files
echo ""
MODIFIED_STAGED_FILES=""
for file in $STAGED_KOTLIN_FILES; do
    if [ -f "$file" ] && ! git diff --quiet -- "$file"; then
        MODIFIED_STAGED_FILES="$MODIFIED_STAGED_FILES$file\n"
    fi
done

if [ -n "$MODIFIED_STAGED_FILES" ]; then
    echo -e "${YELLOW}Auto-formatted files:${NC}"
    echo -e "$MODIFIED_STAGED_FILES" | sed 's/^/  • /'
    echo ""
    echo -e "${YELLOW}Re-staging formatted files...${NC}"
    
    for file in $STAGED_KOTLIN_FILES; do
        if [ -f "$file" ] && ! git diff --quiet -- "$file"; then
            git add "$file"
        fi
    done
    
    echo -e "${GREEN}✅ Formatted files have been re-staged${NC}"
fi

echo -e "${GREEN}✅ All code style checks passed${NC}"
echo -e "${GREEN}✅ All license headers present${NC}"
echo -e "${GREEN}✅ Commit proceeding...${NC}"
restore_stash
exit 0
