#!/bin/bash

################################################################################
# Pre-Push Hook: Security Detection + Tag Validation (GitHub Flow)
# Version: 2.1.0 - Non-interactive mode for CI/automation compatibility
################################################################################

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

# Read stdin ONCE and store all refs
REFS=()
while read local_ref local_oid remote_ref remote_oid; do
    REFS+=("$local_ref $local_oid $remote_ref $remote_oid")
done

###############################################################################
# PHASE 1: Security Secrets Detection (Optimized)
###############################################################################

echo "🔒 Security scan..."

# Combined pattern for single grep (much faster)
COMBINED_PATTERN='(AIzaSy[A-Za-z0-9_-]{35}|sk-[A-Za-z0-9]{48}|sk-ant-api[0-9]{2}-[A-Za-z0-9_-]{90,}|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{36}|gho_[A-Za-z0-9]{36})'

for ref_line in "${REFS[@]}"; do
    read -r local_ref local_oid remote_ref remote_oid <<< "$ref_line"

    # Skip deletions
    [[ "$local_oid" == "0000000000000000000000000000000000000000" ]] && continue

    # Skip tag refs for security check (check branch pushes only)
    [[ "$remote_ref" == refs/tags/* ]] && continue

    # Determine base for diff
    if [[ "$remote_oid" == "0000000000000000000000000000000000000000" ]]; then
        BASE=$(git rev-parse origin/main 2>/dev/null || echo "")
        [[ -z "$BASE" ]] && continue
    else
        BASE="$remote_oid"
    fi

    # Single optimized grep on diff content (added lines only)
    if git diff "$BASE".."$local_oid" 2>/dev/null | grep -E '^\+' | grep -qE "$COMBINED_PATTERN"; then
        echo ""
        echo -e "${RED}❌ SECRETS DETECTED in push!${NC}"
        echo ""
        echo "Commits being pushed:"
        git log --oneline "$BASE".."$local_oid" 2>/dev/null | head -5
        echo ""
        echo -e "${YELLOW}Fix options:${NC}"
        echo "  1. If false positive: git push --no-verify"
        echo "  2. If real secret: Remove and amend commit"
        echo ""
        exit 1
    fi
done

echo -e "${GREEN}✓ No secrets found${NC}"

###############################################################################
# PHASE 2: Tag Validation (Semantic Version + Uniqueness)
###############################################################################

for ref_line in "${REFS[@]}"; do
    read -r local_ref local_oid remote_ref remote_oid <<< "$ref_line"

    # Only process tag refs
    [[ "$remote_ref" != refs/tags/* ]] && continue

    tag_name="${remote_ref#refs/tags/}"
    echo "🏷️  Tag: $tag_name"

    # Validate semantic version format (v1.2.3) - Advisory only, non-blocking
    if [[ ! "$tag_name" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        echo -e "${YELLOW}  ⚠️  Advisory: Non-semantic format (expected v1.2.3)${NC}"
    fi

    # Check for duplicate remote tag - This IS blocking
    if git ls-remote --tags origin "$tag_name" 2>/dev/null | grep -q "$tag_name"; then
        echo ""
        echo -e "${RED}❌ Tag '$tag_name' already exists on remote${NC}"
        echo ""
        echo "Options:"
        echo "  1. Use different version: git tag v{new_version}"
        echo "  2. Delete remote tag: git push origin :refs/tags/$tag_name"
        echo ""
        exit 1
    fi

    echo -e "${GREEN}✓ Tag validated${NC}"
done

echo -e "${GREEN}✅ Pre-push checks passed${NC}"
exit 0
