#!/bin/bash
# Setup script for Git hooks to automatically format Go code

set -e

echo "🔧 Setting up Git hooks for automatic Go formatting..."

# Create hooks directory if it doesn't exist
mkdir -p .git/hooks

# Create the pre-push hook
cat > .git/hooks/pre-push << 'EOF'
#!/bin/bash
# Git pre-push hook to automatically format and lint Go code

set -e

echo "🔍 Running pre-push Go code quality checks..."

# Get the list of Go files that are about to be pushed
files_to_push=$(git diff --cached --name-only --diff-filter=AM | grep '\.go$' || true)

if [ -n "$files_to_push" ]; then
    echo "📁 Found Go files to process:"
    echo "$files_to_push" | sed 's/^/  - /'
    
    # Step 1: Format the files
    echo "📝 Formatting files..."
    echo "$files_to_push" | xargs -I {} gofmt -w {}
    
    # Check if any files were actually changed by formatting
    formatted_files=$(echo "$files_to_push" | xargs -I {} gofmt -l {} || true)
    
    if [ -n "$formatted_files" ]; then
        echo "✨ Formatted files:"
        echo "$formatted_files" | sed 's/^/  - /'
        
        echo "🔄 Re-staging formatted files..."
        echo "$formatted_files" | xargs git add
        
        echo "⚠️  Files were auto-formatted and re-staged. Push again to continue."
        exit 1
    else
        echo "✅ All files were already properly formatted"
    fi
    
    # Step 2: Run linting on the files
    echo "🔍 Running linting on staged files..."
    
    # Check if golangci-lint is available
    if command -v golangci-lint >/dev/null 2>&1; then
        # Create a temporary directory for linting
        temp_dir=$(mktemp -d)
        
        # Copy staged files to temp directory for linting
        for file in $files_to_push; do
            if [ -f "$file" ]; then
                mkdir -p "$temp_dir/$(dirname "$file")"
                cp "$file" "$temp_dir/$file"
            fi
        done
        
        # Run linting on the copied files
        echo "🧪 Running golangci-lint..."
        if cd "$temp_dir" && golangci-lint run ./... --timeout=3m; then
            echo "✅ Linting passed!"
        else
            echo ""
            echo "❌ Linting found issues in your Go code:"
            echo "   - Check the output above for specific issues"
            echo ""
            rm -rf "$temp_dir"
            exit 1
        fi
        
        # Clean up temp directory
        rm -rf "$temp_dir"
        cd - >/dev/null
    else
        echo "⚠️  golangci-lint not found. Skipping linting."
        echo "   Install it with: make golangci-lint"
    fi
    
else
    echo "ℹ️  No Go files found in this push"
fi

# Also format all modified and untracked Go files to keep codebase consistent
echo "🔍 Checking for other modified Go files..."
modified_files=$(git diff --name-only --diff-filter=AM HEAD | grep '\.go$' || true)
untracked_files=$(git ls-files --others --exclude-standard | grep '\.go$' || true)
all_modified="$modified_files $untracked_files"

if [ -n "$all_modified" ]; then
    echo "📝 Auto-formatting modified/untracked Go files..."
    echo "$all_modified" | tr ' ' '\n' | grep -v '^$' | sort -u | xargs -I {} gofmt -w {}
fi

echo "✅ Pre-push quality checks complete"
exit 0
EOF

# Make it executable
chmod +x .git/hooks/pre-push

# Create a pre-commit hook as well (optional, more aggressive)
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Git pre-commit hook to validate Go code formatting

set -e

echo "🔍 Checking Go code formatting..."

# Check staged Go files
staged_files=$(git diff --cached --name-only --diff-filter=AM | grep '\.go$' || true)

if [ -n "$staged_files" ]; then
    # Check if any staged files need formatting
    unformatted=$(echo "$staged_files" | xargs -I {} gofmt -l {} || true)
    
    if [ -n "$unformatted" ]; then
        echo "❌ The following staged Go files need formatting:"
        echo "$unformatted" | sed 's/^/  - /'
        echo ""
        echo "📝 Please run one of the following:"
        echo "  make fmt-staged    # Format only staged files"
        echo "  make fmt-modified  # Format modified + untracked files"
        echo "  make fmt-all       # Format all Go files"
        echo ""
        echo "Then re-stage your files with: git add -u"
        exit 1
    else
        echo "✅ All staged Go files are properly formatted"
    fi
fi

exit 0
EOF

chmod +x .git/hooks/pre-commit

echo "✅ Git hooks installed successfully!"
echo ""
echo "📋 Available formatting commands:"
echo "  make fmt-modified  - Format modified + untracked Go files"
echo "  make fmt-staged    - Format staged Go files"
echo "  make fmt-all       - Format all Go files"
echo ""
echo "📋 Available linting commands:"
echo "  make lint          - Run comprehensive linting"
echo ""
echo "🪝 Active Git hooks:"
echo "  - pre-commit: Validates formatting before commit"
echo "  - pre-push: Auto-formats, lints, and re-stages files before push"
echo ""
echo "💡 Tips:"
echo "  - The pre-push hook will automatically format AND lint your Go files"
echo "  - If formatting occurs, you'll need to push again to continue"
echo "  - If linting fails, fix the issues and push again"
echo "  - Install golangci-lint with: make golangci-lint"
