#!/bin/bash
set -euo pipefail

# =============================================================================
# Metrici Ubuntu Installation Script - Optimized Version
# =============================================================================

# --- Configuration ---
readonly SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
readonly HOME_DIR="${HOME}"

# Request sudo credentials at start (will prompt if needed)
sudo -v

# Keep sudo credentials fresh until script completes
while true; do
    sudo -n true 2>/dev/null
    sleep 60
    kill -0 $$ 2>/dev/null || exit
done &
readonly SUDO_KEEPALIVE_PID=$!
readonly METRICI_DIR="${HOME_DIR}/metrici"
readonly METRICI_OBJECTS_DIR="${METRICI_DIR}/objects"
readonly METRICI_DB_NAME="metrici2"
readonly METRICI_DB_USER="root"
readonly METRICI_DB_PASS="metriciadmin"
readonly TIMEZONE="$(realpath /etc/localtime | awk -F'/usr/share/zoneinfo/' '{ print $2 }')"

# --- Logging ---
log_info()    { echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $*"; }
log_error()   { echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $*" >&2; }
log_success() { echo "[SUCCESS] $(date '+%Y-%m-%d %H:%M:%S') - $*"; }
log_step()    { echo ""; log_info "========== $* =========="; }

# --- Error handling ---
cleanup() {
    local exit_code=$?
    # Kill sudo keepalive process
    kill "$SUDO_KEEPALIVE_PID" 2>/dev/null || true
    if [[ $exit_code -ne 0 ]]; then
        log_error "Script failed with exit code: $exit_code"
        log_error "Please check the error messages above and retry."
    fi
    exit $exit_code
}
trap cleanup EXIT

# --- Validation ---
validate_dependencies() {
    log_step "Validating dependencies"
    local missing_deps=()
    for cmd in wget sudo apt grep sed awk; do
        if ! command -v "$cmd" &>/dev/null; then
            missing_deps+=("$cmd")
        fi
    done
    if [[ ${#missing_deps[@]} -gt 0 ]]; then
        log_error "Missing dependencies: ${missing_deps[*]}"
        exit 1
    fi
    log_success "All dependencies validated"
}

# --- GPU Detection ---
detect_vendor() {
    local card="$1"
    if echo "$card" | grep -q "NVIDIA"; then
        echo "nvidia"
    elif echo "$card" | grep -q "Intel"; then
        echo "intel"
    elif echo "$card" | grep -q "AMD"; then
        echo "amd"
    else
        echo "unknown"
    fi
}

install_intel_drivers() {
    log_step "Installing Intel GPU drivers"
    wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | \
        sudo gpg --yes --dearmor --output /usr/share/keyrings/intel-graphics.gpg
    echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] \
https://repositories.intel.com/gpu/ubuntu noble client" | \
        sudo tee /etc/apt/sources.list.d/intel-gpu-noble.list >/dev/null
    sudo apt update -y
    sudo apt-get install -y libze-intel-gpu1 libze1 intel-opencl-icd intel-gsc \
        libze-dev intel-ocloc
    log_success "Intel drivers installed"
}

install_nvidia_drivers() {
    log_step "Installing NVIDIA GPU drivers"
    sudo apt-get install -y nvidia-driver-590-open libnvidia-compute-590
    log_success "NVIDIA drivers installed"
}

install_amd_drivers() {
    log_step "Installing AMD GPU drivers"
    local deb_file="amdgpu-install_7.2.70200-1_all.deb"
    wget -q "https://repo.radeon.com/amdgpu-install/25.35/ubuntu/noble/${deb_file}"
    sudo apt-get install -y "./${deb_file}"
    sudo apt update -y
    sudo amdgpu-install -y --usecase=opencl --opencl=rocr
    rm -f "${deb_file}"
    log_success "AMD drivers installed"
}

configure_gpu_drivers() {
    log_step "Configuring GPU drivers"
    local vga_cards
    vga_cards=$(lspci | grep 'VGA' | grep 'NVIDIA\|Intel\|AMD' || true)
    
    if [[ -z "$vga_cards" ]]; then
        log_info "No NVIDIA/Intel/AMD VGA cards detected"
        return 0
    fi

    while IFS= read -r card; do
        [[ -z "$card" ]] && continue
        local vendor
        vendor=$(detect_vendor "$card")
        log_info "Processing: $(echo "$card" | cut -c1-60) (Vendor: $vendor)"
        
        case "$vendor" in
            nvidia) install_nvidia_drivers ;;
            intel)  install_intel_drivers ;;
            amd)    install_amd_drivers ;;
            *)      log_info "Unknown vendor, skipping" ;;
        esac
    done <<< "$vga_cards"
    
    sudo usermod -a -G render,video "$(whoami)"
    log_success "GPU drivers configured"
}

# --- System Setup ---
setup_system_packages() {
    log_step "Installing system packages"
    
    # Add PPAs (only once)
    sudo add-apt-repository ppa:quentiumyt/nvtop -y
    sudo add-apt-repository ppa:ondrej/php -y
    sudo add-apt-repository ppa:ondrej/apache2 -y
    
    # Update and upgrade
    sudo apt update -y
    sudo apt upgrade -y
    
    # Install packages in batches
    local utils="clinfo screen sqlite3 gpsd modemmanager smstools nvtop mc chrony gedit ssh"
    local qt5="libqt5sql5-sqlite libqt5quick5 libqt5qml5 libqt5network5t64 libqt5widgets5t64"
    local qt5_gstreamer="libqt5gstreamer-1.0-0 libqt5glib-2.0-0 libqt5gstreamerutils-1.0-0"
    local gstreamer="gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-libav gstreamer1.0-pipewire \
        gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly \
        gstreamer1.0-vaapi gstreamer1.0-x libgstreamer-gl1.0-0 \
        libgstreamer-plugins-bad1.0-0 libgstreamer-plugins-base1.0-0 \
        libgstreamer-plugins-good1.0-0 libgstreamer1.0-0 libgtk-4-media-gstreamer"
    local server="apache2 mysql-server memcached curl net-tools smartmontools plocate zbar-tools"
    local php="php7.4 php7.4-fpm php7.4-cli php7.4-json php7.4-common php7.4-mysql \
        php7.4-zip php7.4-gd php7.4-mbstring php7.4-mcrypt php7.4-memcache \
        php7.4-curl php7.4-xml php7.4-bcmath php-pear"
    
    sudo apt-get install -y $utils $qt5 $qt5_gstreamer $gstreamer $server $php
    sudo apt-mark hold php7.4-*
    
    # Configure Apache + PHP
    sudo a2enmod proxy_fcgi setenvif rewrite
    sudo a2enconf php7.4-fpm
    
    log_success "System packages installed"
}

# --- PHP Configuration ---
configure_php() {
    log_step "Configuring PHP"
    
    local ioncube_url="https://support.metrici.ro/ubuntu2404"
    local ioncube_files=("ioncube_loader_lin_7.4.so" "ioncube_loader_lin_7.4_ts.so")
    
    # Download IonCube
    for file in "${ioncube_files[@]}"; do
        wget -q "${ioncube_url}/${file}"
    done
    
    sudo mkdir -p /usr/local/ioncube
    for file in "${ioncube_files[@]}"; do
        sudo cp -f "$file" /usr/local/ioncube/
    done
    
    # Cleanup downloaded files
    for file in "${ioncube_files[@]}"; do
        rm -f "$file"
    done
    
    # Configure PHP (CLI and FPM)
    local php_configs=("/etc/php/7.4/cli/php.ini" "/etc/php/7.4/fpm/php.ini")
    
    for config in "${php_configs[@]}"; do
        # Add timezone if not exists
        if ! grep -q "date.timezone" "$config"; then
            sudo sed -i '/\[Date\]/a date.timezone = Europe/Bucharest' "$config"
        fi
        # Update timezone to system timezone (use # as delimiter for paths with /)
        sudo sed -i "s#date\.timezone = .*#date.timezone = ${TIMEZONE}#" "$config"
        
        sudo sed -i "s/upload_max_filesize = 2M/upload_max_filesize = 2048M/" "$config"
        sudo sed -i "s/post_max_size = 8M/post_max_size = 3072M/" "$config"
        sudo sed -i "s/max_execution_time = 30/max_execution_time = 600/" "$config"
        sudo sed -i "s/memory_limit = -1/memory_limit = 8192M/" "$config"
        sudo sed -i "s/memory_limit = 128M/memory_limit = 8192M/" "$config"
        sudo sed -i "s/short_open_tag = Off/short_open_tag = On/" "$config"
        # Add zend_extension at the end if not exists
        if ! grep -q "zend_extension" "$config"; then
            echo "zend_extension=/usr/local/ioncube/${ioncube_files[0]}" | sudo tee -a "$config" >/dev/null
        fi
    done
    
    log_success "PHP configured"
}

# --- Apache Configuration ---
configure_apache() {
    log_step "Configuring Apache"
    
    wget -q "https://support.metrici.ro/ubuntu2404/000-default.conf"
    sudo cp -f 000-default.conf /etc/apache2/sites-available/
    rm -f 000-default.conf
    
    echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/servername.conf >/dev/null
    sudo a2enconf servername
    
    sudo systemctl restart php7.4-fpm
    sudo systemctl restart apache2
    
    log_success "Apache configured"
}

# --- MySQL Configuration ---
configure_mysql() {
    log_step "Configuring MySQL"
    
    sudo mysqladmin -u root password "$METRICI_DB_PASS" 2>/dev/null || true
    # Create database if not exists (ignore error if already exists)
    sudo mysqladmin --user=root --password="$METRICI_DB_PASS" create "$METRICI_DB_NAME" 2>/dev/null || true
    
    wget -q "https://support.metrici.ro/ubuntu2404/metrici.sql"
    # Import SQL (use --force to continue on errors like existing users)
    sudo mysql --user=root --password="$METRICI_DB_PASS" --force "$METRICI_DB_NAME" < metrici.sql 2>/dev/null || true
    
    # Add skip-log-bin to MySQL config properly
    if ! grep -q "skip-log-bin" /etc/mysql/mysql.conf.d/mysqld.cnf; then
        echo -e "\nskip-log-bin" | sudo tee -a /etc/mysql/mysql.conf.d/mysqld.cnf >/dev/null
    fi
    sudo systemctl restart mysql
    
    rm -f metrici.sql
    log_success "MySQL configured"
}

# --- Memcached Configuration ---
configure_memcached() {
    log_step "Configuring Memcached"
    echo "CACHESIZE=\"2048\"" | sudo tee -a /etc/default/memcached >/dev/null
    log_success "Memcached configured"
}

# --- Download Helper ---
download_file() {
    local url="$1"
    local filename
    filename=$(basename "$url")
    log_info "Starting download: $filename"
    # Use timeout and continue on failure
    if timeout 120 wget -q --timeout=60 --tries=2 "$url"; then
        log_info "Downloaded: $filename"
    else
        log_error "Failed to download: $filename (continuing anyway)"
    fi
    return 0
}

download_parallel() {
    local -a urls=("$@")
    # Download sequentially (simpler, more reliable)
    for url in "${urls[@]}"; do
        download_file "$url"
    done
    return 0
}

# --- OpenCV Installation ---
install_opencv() {
    log_step "Installing OpenCV"
    
    local opencv_url="https://support.metrici.ro/ubuntu2404"
    local opencv_packages=(
        "opencv-4.11.0-x86_64-dev.deb"
        "opencv-4.11.0-x86_64-libs.deb"
        "opencv-4.11.0-x86_64-licenses.deb"
        "opencv-4.11.0-x86_64-main.deb"
        "opencv-4.11.0-x86_64-python.deb"
        "opencv-4.11.0-x86_64-scripts.deb"
    )
    
    # Download packages individually (ignore failures for missing packages)
    for pkg in "${opencv_packages[@]}"; do
        download_file "${opencv_url}/${pkg}" || true
    done
    
    # Install available packages (ignore missing ones)
    for pkg in "${opencv_packages[@]}"; do
        if [[ -f "$pkg" ]]; then
            sudo apt-get install -y "./${pkg}" 2>/dev/null || true
        fi
    done
    
    # Cleanup
    for pkg in "${opencv_packages[@]}"; do
        rm -f "$pkg"
    done
    
    log_success "OpenCV installed"
}

# --- Metrici Files Installation ---
install_metrici_files() {
    log_step "Installing Metrici files"
    
    local metrici_url="https://support.metrici.ro/ubuntu2404"
    
    # Create directories
    mkdir -p "$METRICI_DIR" "$METRICI_OBJECTS_DIR"
    
    # Main executables
    local executables=("metrici-ac" "metrici-cpan" "metrici-lc" "metrici-lpr" \
        "metrici-lpr-plus" "metrici-ppd")
    for exe in "${executables[@]}"; do
        download_file "${metrici_url}/${exe}" || true
    done
    for exe in "${executables[@]}"; do
        cp -f "$exe" "$METRICI_DIR/"
        chmod +x "$METRICI_DIR/$exe"
        rm -f "$exe"
    done
    
    # Object files
    local objects=("objw.one" "objw.two" "objw.three" "objw.four" "objw.five" \
        "objw.six" "objw.seven" "objw.eight" "objw.nine" "objw.ten" \
        "objw.eleven" "objw.twelve" "objw.thirteen" "objw.zero")
    for obj in "${objects[@]}"; do
        download_file "${metrici_url}/${obj}" || true
    done
    for obj in "${objects[@]}"; do
        cp -f "$obj" "$METRICI_OBJECTS_DIR/"
        rm -f "$obj"
    done
    
    # Configuration and helpers
    local configs=("lv.ini" "laser.wav" "metrici-win.zip")
    for cfg in "${configs[@]}"; do
        download_file "${metrici_url}/${cfg}" || true
    done
    for cfg in "${configs[@]}"; do
        cp -f "$cfg" "$METRICI_DIR/"
        rm -f "$cfg"
    done
    
    # Scripts
    local delete_scripts=("metrici-ac-delete_events_after.sh" "start-metrici.sh" \
        "shmclear.sh" "metrici-shmclear.sh" \
        "metrici-send_jobs.sh" "metrici-watchdog.sh" \
        "metrici-ccr-delete_events_after.sh" "metrici-eer-delete_events_after.sh" \
        "metrici-lc-delete_events_after.sh" "metrici-lpr-delete_events_after.sh" \
        "metrici-ppd-delete_events_after.sh" "metrici-qr-delete_events_after.sh" \
        "metrici-ta-delete_events_after.sh" "metrici-vj-delete_events_after.sh")
    for script in "${delete_scripts[@]}"; do
        download_file "${metrici_url}/${script}" || true
    done
    for script in "${delete_scripts[@]}"; do
        cp -f "$script" "$METRICI_DIR/"
        chmod +x "$METRICI_DIR/$script"
        rm -f "$script"
    done
    
    # Check alarms scripts
    local alarm_scripts=("metrici-ac-check_alarms.sh" "metrici-lc-check_alarms.sh" \
        "metrici-lpr-check_alarms.sh" "metrici-ppd-check_alarms.sh" \
        "metrici-ta-check_alarms.sh")
    for script in "${alarm_scripts[@]}"; do
        download_file "${metrici_url}/${script}" || true
    done
    for script in "${alarm_scripts[@]}"; do
        cp -f "$script" "$METRICI_DIR/"
        chmod +x "$METRICI_DIR/$script"
        rm -f "$script"
    done
    
    # Trigger URLs script
    download_file "${metrici_url}/metrici-lpr-trigger_parking_urls.sh"
    cp -f metrici-lpr-trigger_parking_urls.sh "$METRICI_DIR/"
    chmod +x "$METRICI_DIR/metrici-lpr-trigger_parking_urls.sh"
    rm -f metrici-lpr-trigger_parking_urls.sh
    
    log_success "Metrici files installed"
}

# --- Autostart Configuration ---
configure_autostart() {
    log_step "Configuring autostart"
    
    cat > start-metrici.sh.desktop << EOF
[Desktop Entry]
Type=Application
Exec=${METRICI_DIR}/start-metrici.sh
Hidden=false
NoDisplay=false
X-GNOME-AutostartEnabled=true
Name=metrici
Comment=
EOF
    
    mkdir -p "$HOME_DIR/.config/autostart"
    cp -f start-metrici.sh.desktop "$HOME_DIR/.config/autostart/"
    rm -f start-metrici.sh.desktop
    
    log_success "Autostart configured"
}

# --- License Key Installation ---
install_license_system() {
    log_step "Installing license system"
    
    download_file "https://support.metrici.ro/ubuntu2404/aksusbd-10.13.1.tar.gz"
    tar -xzf aksusbd-10.13.1.tar.gz
    cd aksusbd-10.13.1
    sudo ./dinst
    cd ..
    rm -rf aksusbd-10.13.1 aksusbd-10.13.1.tar.gz
    
    log_success "License system installed"
}

# --- Pylon Camera SDK ---
install_pylon() {
    log_step "Installing Pylon SDK"
    
    download_file "https://support.metrici.ro/ubuntu2404/pylon5.tar.gz"
    sudo mkdir -p /usr/local/lib/pylon
    sudo tar --strip-components=1 -xzf pylon5.tar.gz -C /usr/local/lib/pylon
    sudo ldconfig
    
    download_file "https://support.metrici.ro/ubuntu2404/pylon.conf"
    sudo cp -f pylon.conf /etc/ld.so.conf.d/
    sudo ldconfig
    
    rm -f pylon5.tar.gz pylon.conf
    
    log_success "Pylon SDK installed"
}

# --- Web Interface ---
install_web_interface() {
    log_step "Installing web interface"
    
    download_file "https://support.metrici.ro/ubuntu2404/metrici3.webi.tar.gz"
    sudo tar --strip-components=4 -xzf metrici3.webi.tar.gz -C /var/www/html
    sudo chown -R www-data:www-data /var/www/html
    
    sudo mkdir -p /var/www/metrici_storage
    sudo chown www-data:www-data /var/www/metrici_storage
    sudo chmod 777 /var/www/metrici_storage
    
    sudo rm -f /var/www/html/index.html
    rm -f metrici3.webi.tar.gz
    
    log_success "Web interface installed"
}

# --- PHP Dependencies ---
install_php_dependencies() {
    log_step "Installing PHP dependencies"
    
    local php_deps=("mdba.tar.gz" "driver-mysqli.tar.gz" "PHPMailer.tar.gz")
    log_info "Downloading PHP dependencies..."
    for dep in "${php_deps[@]}"; do
        log_info "Downloading: $dep"
        download_file "https://support.metrici.ro/ubuntu2404/$dep"
    done
    log_info "Downloads complete"
    
    # Extract if files exist (ignore errors)
    if [[ -f "mdba.tar.gz" ]]; then
        log_info "Extracting mdba.tar.gz..."
        sudo mkdir -p /usr/share/php
        sudo tar --strip-components=1 -xzf mdba.tar.gz -C /usr/share/php 2>/dev/null || true
    fi
    if [[ -f "driver-mysqli.tar.gz" ]]; then
        log_info "Extracting driver-mysqli.tar.gz..."
        sudo mkdir -p /usr/share/php
        sudo tar --strip-components=3 -xzf driver-mysqli.tar.gz -C /usr/share/php 2>/dev/null || true
    fi
    if [[ -f "PHPMailer.tar.gz" ]]; then
        log_info "Extracting PHPMailer.tar.gz..."
        sudo mkdir -p /usr/share/php
        sudo tar -xzf PHPMailer.tar.gz -C /usr/share/php 2>/dev/null || true
    fi
    
    rm -f "${php_deps[@]}"
    
    log_success "PHP dependencies installed"
}

# --- Cron Jobs ---
install_cron_jobs() {
    log_step "Installing cron jobs"
    
    local cron_url="https://support.metrici.ro/ubuntu2404"
    local cron_files=("cron-hourly-general.sh" "cron-daily-general.sh" \
        "cron-weekly-general.sh" "cron-monthly-general.sh" \
        "cron-hourly-ac.sh" "cron-hourly-lc.sh" "cron-hourly-ppd.sh")
    
    for file in "${cron_files[@]}"; do
        download_file "${cron_url}/${file}" || true
    done
    
    for file in "${cron_files[@]}"; do
        chmod +x "$file"
    done
    
    sudo cp -f cron-hourly-general.sh /etc/cron.hourly/
    sudo cp -f cron-daily-general.sh /etc/cron.daily/
    sudo cp -f cron-weekly-general.sh /etc/cron.weekly/
    sudo cp -f cron-monthly-general.sh /etc/cron.monthly/
    sudo cp -f cron-hourly-ac.sh /etc/cron.hourly/
    sudo cp -f cron-hourly-lc.sh /etc/cron.hourly/
    sudo cp -f cron-hourly-ppd.sh /etc/cron.hourly/
    
    rm -f "${cron_files[@]}"
    
    log_success "Cron jobs installed"
}

# --- TeamViewer ---
install_teamviewer() {
    log_step "Installing TeamViewer"
    
    download_file "https://download.teamviewer.com/download/linux/teamviewer_amd64.deb"
    sudo apt-get install -y ./teamviewer_amd64.deb
    rm -f teamviewer_amd64.deb
    
    log_success "TeamViewer installed"
}

# --- Firewall Configuration ---
configure_firewall() {
    log_step "Configuring firewall"
    sudo systemctl stop ufw
    sudo systemctl disable ufw
    log_success "Firewall disabled"
}

# --- Generate Install Log ---
generate_install_log() {
    local log_file="${SCRIPT_DIR}/install.log"
    
    {
        echo "=========================================="
        echo "Metrici Installation Summary"
        echo "=========================================="
        echo "Date: $(date '+%Y-%m-%d %H:%M:%S')"
        echo "Hostname: $(hostname)"
        echo "User: $(whoami)"
        echo "System: $(uname -a)"
        echo ""
        echo "Configuration:"
        echo "  - Metrici Directory: ${METRICI_DIR}"
        echo "  - Database: ${METRICI_DB_NAME}"
        echo "  - Timezone: ${TIMEZONE}"
        echo ""
        echo "Installed Components:"
        echo "  - GPU Drivers: $(lspci | grep -E 'VGA|3D' | head -1 || echo 'Not detected')"
        echo "  - Apache: $(apache2 -v 2>/dev/null | grep 'Apache' || echo 'Not installed')"
        echo "  - PHP: $(php -v 2>/dev/null | head -1 || echo 'Not installed')"
        echo "  - MySQL: $(mysql --version 2>/dev/null || echo 'Not installed')"
        echo "  - OpenCV: $(pkg-config --modversion opencv4 2>/dev/null || echo 'Not installed')"
        echo ""
        echo "=========================================="
        echo "Installation completed successfully"
        echo "=========================================="
    } > "$log_file"
    
    log_info "Install log saved to: $log_file"
}

# --- Main Execution ---
main() {
    log_step "Metrici Ubuntu Installation Script"
    log_info "Starting installation process..."
    
    validate_dependencies
    configure_gpu_drivers
    setup_system_packages
    configure_php
    configure_apache
    configure_mysql
    configure_memcached
    install_opencv
    install_metrici_files
    configure_autostart
    install_license_system
    install_pylon
    install_web_interface
    install_php_dependencies
    install_cron_jobs
    install_teamviewer
    configure_firewall
    
    # Final update
    sudo apt update -y
    sudo apt upgrade -y
    
    # Generate install log
    generate_install_log
    
    log_step "Installation Complete"
    echo ""
    echo "=========================================="
    echo "Good... now please reboot the system"
    echo "=========================================="
    echo ""
}

main "$@"
