#!/bin/bash
################################################################################
# Bot Blocker - Apache User-Agent Blocking Manager
################################################################################
# Blocks malicious bots, scrapers, and AI crawlers at Apache level
# Safe implementation with backup, validation, and rollback
################################################################################

# Source common functions
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../lib/common-functions.sh" 2>/dev/null || {
    echo "[ERROR] Cannot load common-functions.sh"
    exit 1
}

# Detect control panel and system (optional)
if type -t detect_system &>/dev/null; then
    detect_system
fi

# Configuration
APACHE_CONF="/etc/apache2/conf.d/includes/pre_main_global.conf"
BACKUP_DIR="/root/.bot-blocker-backups"
MARKER_START="# BEGIN Bot Blocker - Managed by Server Toolkit"
MARKER_END="# END Bot Blocker"

# Default bot list (security scanners, aggressive SEO bots, AI crawlers)
DEFAULT_BOT_LIST="nikto|nmap|masscan|sqlmap|havij|acunetix|nessus|burp|metasploit|AhrefsBot|SemrushBot|MJ12bot|DotBot|Meta-ExternalAgent|Go-http-client|ChatGPT-User|GPTBot|Google-Extended|anthropic-ai|Claude-Web|CCBot|Omgilibot|FacebookBot|Bytespider|PerplexityBot"

################################################################################
# Helper Functions
################################################################################

check_apache_installed() {
    if ! command -v httpd &>/dev/null; then
        print_error "Apache is not installed"
        return 1
    fi
    return 0
}

check_apache_config_exists() {
    local conf_dir=$(dirname "$APACHE_CONF")

    if [ ! -d "$conf_dir" ]; then
        print_warning "Apache config directory doesn't exist: $conf_dir"
        echo ""
        if ! confirm "Create directory?"; then
            return 1
        fi
        mkdir -p "$conf_dir"
        print_success "Created directory: $conf_dir"
    fi

    if [ ! -f "$APACHE_CONF" ]; then
        print_info "Config file doesn't exist, will be created: $APACHE_CONF"
        touch "$APACHE_CONF"
    fi

    return 0
}

is_bot_blocking_enabled() {
    if [ ! -f "$APACHE_CONF" ]; then
        return 1
    fi

    grep -q "$MARKER_START" "$APACHE_CONF" 2>/dev/null
}

create_backup() {
    mkdir -p "$BACKUP_DIR"

    local backup_file="$BACKUP_DIR/pre_main_global.conf.$(date +%Y%m%d_%H%M%S)"

    if [ -f "$APACHE_CONF" ]; then
        cp "$APACHE_CONF" "$backup_file"
        print_success "Backup created: $backup_file"
        echo "$backup_file"
    else
        # No existing file to backup
        echo ""
    fi
}

validate_apache_syntax() {
    print_info "Validating Apache configuration..."

    if httpd -t 2>&1 | grep -q "Syntax OK"; then
        print_success "Apache configuration syntax is valid"
        return 0
    else
        print_error "Apache configuration has syntax errors:"
        echo ""
        httpd -t 2>&1 | grep -v "Syntax OK"
        return 1
    fi
}

restart_apache() {
    print_info "Restarting Apache..."

    if systemctl restart httpd; then
        print_success "Apache restarted successfully"
        return 0
    else
        print_error "Failed to restart Apache"
        return 1
    fi
}

restore_backup() {
    local backup_file="$1"

    if [ -f "$backup_file" ]; then
        cp "$backup_file" "$APACHE_CONF"
        print_success "Configuration restored from backup"
        restart_apache
    else
        print_error "Backup file not found: $backup_file"
    fi
}

################################################################################
# Core Functions
################################################################################

enable_bot_blocking() {
    print_banner "Enable Bot Blocking"

    # Check prerequisites
    if ! check_apache_installed; then
        press_enter
        return 1
    fi

    if ! check_apache_config_exists; then
        press_enter
        return 1
    fi

    # Check if already enabled
    if is_bot_blocking_enabled; then
        print_warning "Bot blocking is already enabled"
        echo ""
        if ! confirm "Re-apply configuration?"; then
            return 0
        fi
        disable_bot_blocking_silent
    fi

    echo ""
    echo "Bot Blocking Configuration:"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    echo "This will block the following types of bots:"
    echo ""
    echo "  🔴 Security Scanners:"
    echo "     nikto, nmap, masscan, sqlmap, havij, acunetix, nessus, burp, metasploit"
    echo ""
    echo "  🟡 Aggressive SEO Bots:"
    echo "     AhrefsBot, SemrushBot, MJ12bot, DotBot"
    echo ""
    echo "  🟣 AI Crawlers:"
    echo "     ChatGPT-User, GPTBot, Google-Extended, Claude-Web, anthropic-ai"
    echo ""
    echo "  🔵 Generic Scrapers:"
    echo "     Go-http-client, Meta-ExternalAgent, CCBot, Omgilibot, FacebookBot,"
    echo "     Bytespider, PerplexityBot"
    echo ""
    echo "Configuration file: $APACHE_CONF"
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    read -p "Proceed with enabling bot blocking? (yes/no): " confirm

    if [ "$confirm" != "yes" ]; then
        echo "Cancelled."
        press_enter
        return 0
    fi

    # Create backup
    echo ""
    local backup_file=$(create_backup)

    # Add bot blocking rules
    echo ""
    print_info "Adding bot blocking rules..."

    # Build the configuration with variables expanded
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')

    cat >> "$APACHE_CONF" <<EOF

# BEGIN Bot Blocker - Managed by Server Toolkit
# Blocks malicious bots, scrapers, and AI crawlers
# Last updated: ${timestamp}
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} "(${DEFAULT_BOT_LIST})" [NC]
    RewriteRule ^ - [F,L]
</IfModule>
# END Bot Blocker

EOF

    print_success "Bot blocking rules added"

    # Validate syntax
    echo ""
    if ! validate_apache_syntax; then
        print_error "Configuration validation failed!"
        echo ""
        read -p "Rollback to previous configuration? (yes/no): " rollback
        if [ "$rollback" = "yes" ] && [ -n "$backup_file" ]; then
            restore_backup "$backup_file"
        fi
        press_enter
        return 1
    fi

    # Restart Apache
    echo ""
    if restart_apache; then
        echo ""
        print_success "═══════════════════════════════════════════════════════"
        print_success "Bot blocking enabled successfully!"
        print_success "═══════════════════════════════════════════════════════"
        echo ""
        echo "What happens now:"
        echo "  ✓ Blocked bots receive HTTP 403 Forbidden"
        echo "  ✓ Legitimate traffic is unaffected"
        echo "  ✓ Configuration survives Apache restarts"
        echo ""
        echo "To disable: Use option 2 from the menu"
        echo ""
    else
        print_error "Failed to restart Apache"
        if [ -n "$backup_file" ]; then
            echo ""
            read -p "Rollback to previous configuration? (yes/no): " rollback
            if [ "$rollback" = "yes" ]; then
                restore_backup "$backup_file"
            fi
        fi
    fi

    press_enter
}

disable_bot_blocking_silent() {
    # Silent version for internal use (re-apply scenario)
    if [ -f "$APACHE_CONF" ]; then
        sed -i "/$MARKER_START/,/$MARKER_END/d" "$APACHE_CONF"
    fi
}

disable_bot_blocking() {
    print_banner "Disable Bot Blocking"

    # Check if enabled
    if ! is_bot_blocking_enabled; then
        print_warning "Bot blocking is not currently enabled"
        press_enter
        return 0
    fi

    echo ""
    echo "This will remove bot blocking rules from:"
    echo "  $APACHE_CONF"
    echo ""
    read -p "Proceed with disabling bot blocking? (yes/no): " confirm

    if [ "$confirm" != "yes" ]; then
        echo "Cancelled."
        press_enter
        return 0
    fi

    # Create backup
    echo ""
    local backup_file=$(create_backup)

    # Remove bot blocking rules
    echo ""
    print_info "Removing bot blocking rules..."

    sed -i "/$MARKER_START/,/$MARKER_END/d" "$APACHE_CONF"

    print_success "Bot blocking rules removed"

    # Validate syntax
    echo ""
    if ! validate_apache_syntax; then
        print_error "Configuration validation failed!"
        echo ""
        read -p "Rollback to previous configuration? (yes/no): " rollback
        if [ "$rollback" = "yes" ] && [ -n "$backup_file" ]; then
            restore_backup "$backup_file"
        fi
        press_enter
        return 1
    fi

    # Restart Apache
    echo ""
    if restart_apache; then
        echo ""
        print_success "Bot blocking disabled successfully"
        echo ""
    else
        print_error "Failed to restart Apache"
        if [ -n "$backup_file" ]; then
            echo ""
            read -p "Rollback to previous configuration? (yes/no): " rollback
            if [ "$rollback" = "yes" ]; then
                restore_backup "$backup_file"
            fi
        fi
    fi

    press_enter
}

view_configuration() {
    print_banner "Current Bot Blocking Configuration"

    if ! is_bot_blocking_enabled; then
        print_warning "Bot blocking is not currently enabled"
        echo ""
        echo "Use option 1 to enable bot blocking"
        press_enter
        return 0
    fi

    echo ""
    echo "Status: ${GREEN}Enabled${NC}"
    echo "Config file: $APACHE_CONF"
    echo ""
    echo "Current rules:"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

    # Extract and display bot blocking section
    sed -n "/$MARKER_START/,/$MARKER_END/p" "$APACHE_CONF"

    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""

    # Parse and display bot list
    local bot_list=$(sed -n "/$MARKER_START/,/$MARKER_END/p" "$APACHE_CONF" | grep "RewriteCond.*HTTP_USER_AGENT" | sed 's/.*"(\(.*\))".*/\1/')

    if [ -n "$bot_list" ]; then
        echo "Blocked User-Agents:"
        echo ""
        echo "$bot_list" | tr '|' '\n' | nl | column -t
        echo ""
    fi

    press_enter
}

test_configuration() {
    print_banner "Test Apache Configuration"

    echo ""
    print_info "Running Apache syntax check..."
    echo ""

    if validate_apache_syntax; then
        echo ""
        print_success "Configuration is valid and ready to apply"
    else
        echo ""
        print_error "Configuration has errors - fix before applying"
    fi

    echo ""
    press_enter
}

manage_backups() {
    print_banner "Backup Management"

    if [ ! -d "$BACKUP_DIR" ] || [ -z "$(ls -A "$BACKUP_DIR" 2>/dev/null)" ]; then
        print_warning "No backups found"
        echo ""
        echo "Backups are created automatically when you enable/disable bot blocking"
        press_enter
        return 0
    fi

    echo ""
    echo "Available backups:"
    echo ""

    local count=1
    while IFS= read -r backup; do
        local size=$(du -h "$backup" | cut -f1)
        local date=$(basename "$backup" | sed 's/pre_main_global.conf.//')
        echo "  $count) $date ($size)"
        count=$((count + 1))
    done < <(ls -t "$BACKUP_DIR"/*.conf.* 2>/dev/null)

    echo ""
    echo "  0) Back to menu"
    echo ""
    read -p "Select backup to restore (or 0 to cancel): " selection

    if [ "$selection" = "0" ]; then
        return 0
    fi

    local backup_file=$(ls -t "$BACKUP_DIR"/*.conf.* 2>/dev/null | sed -n "${selection}p")

    if [ -z "$backup_file" ]; then
        print_error "Invalid selection"
        press_enter
        return 1
    fi

    echo ""
    echo "Selected backup: $(basename "$backup_file")"
    echo ""
    read -p "Restore this backup? (yes/no): " confirm

    if [ "$confirm" = "yes" ]; then
        restore_backup "$backup_file"
        echo ""
        print_success "Backup restored successfully"
    fi

    press_enter
}

################################################################################
# Main Menu
################################################################################

show_menu() {
    clear
    print_banner "Bot Blocker - Apache User-Agent Management"

    # Show status
    if is_bot_blocking_enabled; then
        echo -e "Status: ${GREEN}●${NC} Enabled"
    else
        echo -e "Status: ${RED}○${NC} Disabled"
    fi

    echo ""
    echo -e "${BOLD}Configuration:${NC}"
    echo ""
    echo -e "  ${CYAN}1)${NC} Enable Bot Blocking   - Block malicious bots and scrapers"
    echo -e "  ${CYAN}2)${NC} Disable Bot Blocking  - Remove blocking rules"
    echo -e "  ${CYAN}3)${NC} View Configuration    - Show current rules"
    echo ""
    echo -e "${BOLD}Maintenance:${NC}"
    echo ""
    echo -e "  ${CYAN}4)${NC} Test Configuration    - Validate Apache syntax"
    echo -e "  ${CYAN}5)${NC} Manage Backups        - View and restore backups"
    echo ""
    echo -e "  ${RED}0)${NC} Back to Security Menu"
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo -n "Select option (0-5): "
}

main() {
    while true; do
        show_menu

        # Validate choice input
        while true; do
            read -r choice

            if ! [[ "$choice" =~ ^[0-5]$ ]]; then
                echo ""
                print_error "Invalid choice. Please enter 0-5"
                echo ""
                continue
            fi
            break
        done

        case $choice in
            1) enable_bot_blocking ;;
            2) disable_bot_blocking ;;
            3) view_configuration ;;
            4) test_configuration ;;
            5) manage_backups ;;
            0)
                clear
                exit 0
                ;;
        esac
    done
}

# Run main menu
main
