#!/bin/bash

#==============================================================================
# Animex Extension Server Startup Script
# Description: Professional startup script with comprehensive error handling,
#              logging, and environment management for Animex Extension Server
# Author: Animex Developer (Indie)
# Date: 2023-10-01
# License: GPL-3.0
# Version: 2.0
#==============================================================================

set -euo pipefail  # Exit on error, undefined vars, pipe failures

#==============================================================================
# CONFIGURATION
#==============================================================================

readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly VENV_DIR="${SCRIPT_DIR}/venv"
readonly REQUIREMENTS="${SCRIPT_DIR}/requirements.txt"
readonly FIRST_RUN_FLAG="${SCRIPT_DIR}/.first_run_complete"
readonly LOGO_FILE="${SCRIPT_DIR}/logo.txt"
readonly LOG_FILE="${SCRIPT_DIR}/startup.log"

readonly APP_NAME="Animex Extension Server"
readonly APP_HOST="${APP_HOST:-0.0.0.0}"
readonly APP_PORT="${APP_PORT:-7275}"
readonly PYTHON_CMD="${PYTHON_CMD:-python3}"

#==============================================================================
# UTILITY FUNCTIONS
#==============================================================================

# Logging function with timestamps
log() {
    local level="$1"
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}

log_info() { log "INFO" "$@"; }
log_warn() { log "WARN" "$@"; }
log_error() { log "ERROR" "$@"; }

# Display colored output
print_colored() {
    local color_code="$1"
    local message="$2"
    echo -e "\033[${color_code}m${message}\033[0m"
}

print_success() { print_colored "1;32" "$1"; }
print_warning() { print_colored "1;33" "$1"; }
print_error() { print_colored "1;31" "$1"; }
print_info() { print_colored "1;36" "$1"; }
print_orange() { print_colored "1;38;5;208" "$1"; }

# Display Animex logo in bright orange
display_logo() {
    echo ""
    if [[ -f "$LOGO_FILE" ]]; then
        print_orange "$(cat "$LOGO_FILE")"
        echo ""
        print_orange "╔══════════════════════════════════════════════════════════════════════════╗"
        print_orange "║                        ANIMEX EXTENSION SERVER                           ║"
        print_orange "║                     Advanced Anime Streaming Platform                    ║"
        print_orange "╚══════════════════════════════════════════════════════════════════════════╝"
    else
        print_orange "╔══════════════════════════════════════════════════════════════════════════╗"
        print_orange "║                        ANIMEX EXTENSION SERVER                           ║"
        print_orange "║                     Advanced Anime Streaming Platform                    ║"
        print_orange "╚══════════════════════════════════════════════════════════════════════════╝"
        log_warn "Logo file not found: $LOGO_FILE"
    fi
    echo ""
}

# Check system requirements
check_requirements() {
    log_info "Checking system requirements for Animex Extension Server..."
    
    if ! command -v "$PYTHON_CMD" &> /dev/null; then
        log_error "Python 3 is not installed or not in PATH"
        print_error "ERROR: $PYTHON_CMD command not found. Please install Python 3."
        exit 1
    fi
    
    local python_version
    python_version=$("$PYTHON_CMD" --version 2>&1 | cut -d' ' -f2)
    log_info "Found Python version: $python_version"
    
    if ! "$PYTHON_CMD" -m venv --help &> /dev/null; then
        log_error "Python venv module is not available"
        print_error "ERROR: Python venv module not found. Please install python3-venv."
        exit 1
    fi
    
    log_info "System requirements check passed for Animex Extension Server"
}

# Create and setup virtual environment
setup_virtual_environment() {
    log_info "Setting up Animex Extension Server virtual environment at: $VENV_DIR"
    
    if [[ ! -d "$VENV_DIR" ]]; then
        print_info "🔧 Creating Animex virtual environment..."
        if ! "$PYTHON_CMD" -m venv "$VENV_DIR"; then
            log_error "Failed to create virtual environment"
            print_error "ERROR: Failed to create virtual environment"
            exit 1
        fi
        log_info "Animex virtual environment created successfully"
        print_success "✓ Animex virtual environment created"
    else
        log_info "Animex virtual environment already exists"
        print_info "🔧 Animex virtual environment already exists"
    fi
}

# Activate virtual environment
activate_virtual_environment() {
    local activate_script="${VENV_DIR}/bin/activate"
    
    if [[ ! -f "$activate_script" ]]; then
        log_error "Virtual environment activation script not found: $activate_script"
        print_error "ERROR: Virtual environment is corrupted. Please delete the venv directory and try again."
        exit 1
    fi
    
    # shellcheck source=/dev/null
    source "$activate_script"
    log_info "Animex virtual environment activated"
    print_success "✓ Animex virtual environment activated"
}

#==============================================================================
# MODULE & EXTENSION REQUIREMENTS MANAGEMENT
#==============================================================================

# Extract requirements from .module files
extract_module_requirements() {
    local modules_dir="${SCRIPT_DIR}/modules"
    local temp_req_file="$1"
    
    if [[ ! -d "$modules_dir" ]]; then
        return 0
    fi
    
    while IFS= read -r -d '' module_file; do
        local json_header
        json_header=$(sed -n '2,/^---$/p' "$module_file" | sed '$d' 2>/dev/null)
        
        if [[ -n "$json_header" ]]; then
            local requirements
            requirements=$("$PYTHON_CMD" -c "
import json, sys
try:
    data = json.loads('''$json_header''')
    reqs = data.get('requirements', [])
    for req in reqs: print(req)
except: pass
" 2>/dev/null)
            
            if [[ -n "$requirements" ]]; then
                echo "$requirements" >> "$temp_req_file"
            fi
        fi
    done < <(find "$modules_dir" -name "*.module" -type f -print0)
}

# Check and free required ports
check_and_free_ports() {
    local ports=(7275 7277)

    for port in "${ports[@]}"; do
        log_info "Checking if port $port is in use..."

        local pids
        pids=$(lsof -ti tcp:"$port" || true)

        if [[ -n "$pids" ]]; then
            log_warn "Port $port is already in use by PID(s): $pids"
            print_warning "⚠ Port $port is in use. Attempting to stop process(es)..."

            # Try graceful shutdown first
            kill $pids 2>/dev/null || true
            sleep 2

            # Force kill if still alive
            for pid in $pids; do
                if kill -0 "$pid" 2>/dev/null; then
                    log_warn "PID $pid did not terminate gracefully. Force killing..."
                    kill -9 "$pid" 2>/dev/null || true
                fi
            done

            sleep 1
        fi

        # Final verification
        if lsof -ti tcp:"$port" &>/dev/null; then
            log_error "Port $port is still in use after kill attempts"
            print_error "❌ Failed to free port $port. Aborting startup."
            exit 1
        else
            log_info "Port $port is free"
            print_success "✓ Port $port is available"
        fi
    done
}


# Extract requirements from extension package.json files
extract_extension_requirements() {
    local extensions_dir="${SCRIPT_DIR}/extensions"
    local temp_req_file="$1"

    if [[ ! -d "$extensions_dir" ]]; then
        return 0
    fi

    while IFS= read -r -d '' pkg_file; do
        local requirements
        requirements=$("$PYTHON_CMD" -c "
import json, sys
try:
    with open('$pkg_file', 'r') as f:
        data = json.load(f)
    reqs = data.get('requirements', [])
    for req in reqs: print(req)
except: pass
" 2>/dev/null)

        if [[ -n "$requirements" ]]; then
            echo "$requirements" >> "$temp_req_file"
        fi
    done < <(find "$extensions_dir" -name "package.json" -type f -print0)
}

# Install Python dependencies with module and extension requirements
install_dependencies() {
    local temp_requirements="${SCRIPT_DIR}/.temp_all_requirements.txt"
    
    # Clear temp file
    > "$temp_requirements"
    
    # Extract requirements from both modules and extensions
    extract_module_requirements "$temp_requirements"
    extract_extension_requirements "$temp_requirements"
    
    # Consolidate and count unique requirements
    local final_reqs_count=0
    if [[ -s "$temp_requirements" ]]; then
        sort -u "$temp_requirements" -o "$temp_requirements"
        final_reqs_count=$(wc -l < "$temp_requirements")
    fi

    # Backup original requirements.txt
    local backup_requirements="${SCRIPT_DIR}/.requirements_backup.txt"
    if [[ -f "$REQUIREMENTS" ]]; then
        cp "$REQUIREMENTS" "$backup_requirements"
    fi

    # Merge all requirements
    {
        if [[ -f "$backup_requirements" ]]; then
            cat "$backup_requirements"
        fi
        if [[ $final_reqs_count -gt 0 ]]; then
            echo ""
            echo "# Auto-generated module & extension requirements"
            cat "$temp_requirements"
        fi
    } > "$REQUIREMENTS"

    if [[ $final_reqs_count -gt 0 ]]; then
        log_info "Merged $final_reqs_count unique requirements from modules/extensions."
        print_success "✓ Found and added $final_reqs_count additional requirements."
    fi

    if [[ ! -f "$REQUIREMENTS" ]]; then
        log_warn "Requirements file not found: $REQUIREMENTS"
        print_warning "WARNING: requirements.txt not found. Server might not run correctly."
        return 0
    fi
    
    log_info "Installing/updating dependencies from: $REQUIREMENTS"
    print_info "📦 Installing required packages..."
    
    # Upgrade pip first
    pip install --upgrade pip >> "$LOG_FILE" 2>&1
    
    # Install all requirements
    if ! pip install -r "$REQUIREMENTS" >> "$LOG_FILE" 2>&1; then
        log_error "Failed to install dependencies. Check $LOG_FILE for details."
        print_error "ERROR: Failed to install packages. Check log file."
        # Restore original requirements before exiting
        if [[ -f "$backup_requirements" ]]; then mv "$backup_requirements" "$REQUIREMENTS"; fi
        rm -f "$temp_requirements"
        deactivate 2>/dev/null || true
        exit 1
    fi
    
    # Restore original requirements.txt
    if [[ -f "$backup_requirements" ]]; then
        mv "$backup_requirements" "$REQUIREMENTS"
    else
        # If no backup, just clear the generated part
        > "$REQUIREMENTS"
    fi
    rm -f "$temp_requirements"

    log_info "Dependencies installed successfully"
    print_success "✓ Dependencies installed"
}

# Perform first-time setup
first_time_setup() {
    print_orange "🚀 Performing Animex Extension Server first-time setup..."
    log_info "Starting Animex Extension Server first-time setup"
    
    check_requirements
    setup_virtual_environment
    activate_virtual_environment
    install_dependencies
    
    touch "$FIRST_RUN_FLAG"
    log_info "Animex Extension Server first-time setup completed"
    print_success "✓ Animex Extension Server first-time setup completed"
}

# Start the Animex Extension Server
start_application() {
    log_info "Starting $APP_NAME on http://$APP_HOST:$APP_PORT"
    print_orange "🎬 Starting Animex Extension Server..."
    print_orange "🌐 Server URL: http://$APP_HOST:$APP_PORT"
    print_orange "📺 Animex Extension Server is ready for anime streaming!"
    print_info "Press CTRL+C to stop the Animex server"
    echo ""
    
    # Check if uvicorn is available
    if ! command -v uvicorn &> /dev/null; then
        log_error "uvicorn not found in virtual environment"
        print_error "ERROR: uvicorn is not installed. Please check your requirements.txt"
        exit 1
    fi
    
    # Check if live reload is enabled
    if [[ "${LIVE_RELOAD:-false}" == "true" ]]; then
        print_info "🔄 Live reload is enabled - server will restart on file changes"
        # Start the server with file watching
        python watch.py
    else
        # Start the server normally
        uvicorn app:app --host "$APP_HOST" --port "$APP_PORT" --log-level info
    fi
}

# Cleanup function
cleanup() {
    local exit_code=$?
    log_info "Shutting down Animex Extension Server (exit code: $exit_code)"
    
    # Clean up any remaining temporary requirement files
    rm -f "${SCRIPT_DIR}/.temp_module_requirements.txt" "${SCRIPT_DIR}/.requirements_backup.txt"
    
    if [[ -n "${VIRTUAL_ENV:-}" ]]; then
        deactivate 2>/dev/null || true
        log_info "Animex virtual environment deactivated"
        print_info "🔧 Animex virtual environment deactivated"
    fi
    
    print_orange "🛑 Animex Extension Server stopped"
    log_info "Animex Extension Server shutdown complete"
    exit $exit_code
}

# Display help information
show_help() {
    cat << EOF
Usage: $0 [OPTIONS]

Animex Extension Server - Advanced Anime Streaming Platform

OPTIONS:
    -h, --help      Show this help message
    --clean         Remove virtual environment and start fresh
    --check         Check system requirements only
    --live          Enable live reload - server will restart on file changes
    --version       Show script version

ENVIRONMENT VARIABLES:
    APP_HOST        Server host (default: 0.0.0.0)
    APP_PORT        Server port (default: 7275)
    PYTHON_CMD      Python command (default: python3)

EXAMPLES:
    $0              Start Animex Extension Server
    $0 --clean      Clean install Animex Extension Server
    APP_PORT=8080 $0    Start Animex on port 8080

ABOUT ANIMEX:
    Animex Extension Server is an advanced anime streaming platform
    designed to provide seamless anime content delivery and management.

EOF
}

#==============================================================================
# MAIN EXECUTION
#==============================================================================

main() {
    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            --clean)
                print_info "🧹 Cleaning Animex virtual environment..."
                rm -rf "$VENV_DIR" "$FIRST_RUN_FLAG"
                log_info "Clean install requested - removed Animex venv and first run flag"
                ;;
            --check)
                check_requirements
                print_success "✓ Animex system requirements check passed"
                exit 0
                ;;
            --live)
                export LIVE_RELOAD=true
                print_info "🔄 Live reload enabled"
                log_info "Live reload feature enabled"
                ;;
            --version)
                echo "Animex Extension Server Startup Script v2.0"
                exit 0
                ;;
            *)
                print_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
        shift
    done
    
    # Set up signal handlers
    trap cleanup EXIT INT TERM
    
    # Initialize log file
    echo "=== Animex Extension Server Startup - $(date) ===" >> "$LOG_FILE"
    
    # Display Animex logo
    display_logo
    
    # Check if this is first run
    if [[ ! -f "$FIRST_RUN_FLAG" ]]; then
        first_time_setup
    else
        print_orange "🎉 Welcome back to Animex Extension Server!"
        log_info "Returning Animex user detected"
        check_requirements
    fi
    
    # Activate virtual environment
    activate_virtual_environment
    
    # Install/update dependencies
    install_dependencies
    
    echo ""
    echo "✅ All systems go! Starting Animex Extension Server... Checking ports..."
    check_and_free_ports
    
    # Start the Animex Extension Server
    start_application
}

# Execute main function with all arguments
main "$@"