#!/bin/bash
# SMG AIO Downloader Script
# This script downloads and installs the modular SMG AIO system
# Handles: fresh installs, updates, broken repos, missing dependencies
# Version: 3.5.1

# Don't exit on error - we handle errors manually
# set -e

# ============================================
# Configuration
# ============================================
BASEURL="https://install.smg.com.tr/SMGaio"
INSTALL_DIR="/opt/smgaio"
TARBALL="smgaio_modular.tar.gz"
LOG_FILE="/var/log/smgaio_install.log"
VERSION="3.5.2"

# Expected hash for the tarball (update this when you upload new version)
EXPECTED_HASH="495c5a68321911655eecdddc6800a3dfa4e702de468126fcfe473089226ed00b"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# ============================================
# Logging Functions
# ============================================
log() {
    local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
    echo -e "$msg" | tee -a "$LOG_FILE"
}

log_success() {
    echo -e "${GREEN}✓ $1${NC}" | tee -a "$LOG_FILE"
}

log_warning() {
    echo -e "${YELLOW}⚠ $1${NC}" | tee -a "$LOG_FILE"
}

log_error() {
    echo -e "${RED}✗ $1${NC}" | tee -a "$LOG_FILE"
}

log_info() {
    echo -e "${BLUE}ℹ $1${NC}" | tee -a "$LOG_FILE"
}

# ============================================
# Root Check
# ============================================
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        log_error "This script must be run as root (use sudo)"
        echo "Usage: sudo bash $0"
        exit 1
    fi
    log_success "Running as root"
}

# ============================================
# Device Detection
# ============================================
detect_device() {
    local ARCHITECTURE=$(uname -a)
    local SUPPORTED_DEVICES=("meson64" "raspberrypi" "tinkerboard" "smglinux" "x86_64" "i386" "i686" "smgplayer")
    
    for DEVICE in "${SUPPORTED_DEVICES[@]}"; do
        if echo "$ARCHITECTURE" | grep -qi "$DEVICE"; then
            echo "$DEVICE"
            return 0
        fi
    done

    # Fallback: Check architecture
    local ARCH=$(uname -m)
    case "$ARCH" in
        x86_64)
            echo "x86_64"
            return 0
            ;;
        i386|i686)
            echo "i386"
            return 0
            ;;
        armv7l|armhf)
            echo "smgplayer"
            return 0
            ;;
        aarch64|arm64)
            echo "meson64"
            return 0
            ;;
    esac

    log_error "Device not supported: $ARCHITECTURE"
    exit 1
}

# ============================================
# Network Check
# ============================================
check_network() {
    log_info "Checking network connectivity..."
    
    # Try multiple endpoints
    local ENDPOINTS=("8.8.8.8" "1.1.1.1" "google.com")
    local CONNECTED=false
    
    for endpoint in "${ENDPOINTS[@]}"; do
        if ping -c 1 -W 3 "$endpoint" &>/dev/null; then
            CONNECTED=true
            break
        fi
    done
    
    if ! $CONNECTED; then
        log_error "No network connectivity detected"
        log_info "Please check your network connection and try again"
        exit 1
    fi
    
    log_success "Network connectivity OK"
}

# ============================================
# Fix Broken Repos (Debian/Ubuntu)
# ============================================
fix_repositories() {
    log_info "Checking and fixing package repositories..."
    
    local OS_ID=""
    local OS_VERSION=""
    
    # Detect OS
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS_ID="$ID"
        OS_VERSION="$VERSION_CODENAME"
    fi
    
    log_info "Detected OS: $OS_ID ($OS_VERSION)"
    
    # Backup existing sources.list
    if [ -f /etc/apt/sources.list ]; then
        cp /etc/apt/sources.list /etc/apt/sources.list.backup.$(date +%Y%m%d%H%M%S)
        log_info "Backed up existing sources.list"
    fi
    
    # Fix based on OS
    case "$OS_ID" in
        debian)
            fix_debian_repos "$OS_VERSION"
            ;;
        ubuntu)
            fix_ubuntu_repos "$OS_VERSION"
            ;;
        raspbian)
            fix_raspbian_repos "$OS_VERSION"
            ;;
        *)
            log_warning "Unknown OS, attempting generic Debian fix..."
            fix_debian_repos "bullseye"
            ;;
    esac
    
    # Clean and update
    apt-get clean || true
    rm -rf /var/lib/apt/lists/* || true
    
    # Try to update with error handling
    log_info "Updating package lists..."
    apt-get update 2>&1 | tee -a "$LOG_FILE" || true
    
    log_success "Repository fix completed"
}

fix_debian_repos() {
    local VERSION="${1:-bullseye}"
    
    log_info "Setting up Debian $VERSION repositories..."
    
    # Note: bullseye-backports is no longer available (Debian moved to LTS)
    cat > /etc/apt/sources.list << EOF
# Debian $VERSION repositories
deb http://deb.debian.org/debian $VERSION main contrib non-free
deb-src http://deb.debian.org/debian $VERSION main contrib non-free

deb http://deb.debian.org/debian $VERSION-updates main contrib non-free
deb-src http://deb.debian.org/debian $VERSION-updates main contrib non-free

deb http://security.debian.org/debian-security $VERSION-security main contrib non-free
deb-src http://security.debian.org/debian-security $VERSION-security main contrib non-free
EOF
}

fix_ubuntu_repos() {
    local VERSION="${1:-focal}"
    
    log_info "Setting up Ubuntu $VERSION repositories..."
    
    cat > /etc/apt/sources.list << EOF
# Ubuntu $VERSION repositories
deb http://archive.ubuntu.com/ubuntu $VERSION main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu $VERSION-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu $VERSION-security main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu $VERSION-backports main restricted universe multiverse
EOF
}

fix_raspbian_repos() {
    local VERSION="${1:-bullseye}"
    
    log_info "Setting up Raspbian $VERSION repositories..."
    
    cat > /etc/apt/sources.list << EOF
# Raspbian $VERSION repositories
deb http://raspbian.raspberrypi.org/raspbian/ $VERSION main contrib non-free rpi
EOF
    
    # Also fix raspi.list if exists
    if [ -d /etc/apt/sources.list.d ]; then
        cat > /etc/apt/sources.list.d/raspi.list << EOF
deb http://archive.raspberrypi.org/debian/ $VERSION main
EOF
    fi
}

# ============================================
# Install Dependencies
# ============================================
install_dependencies() {
    log_info "Installing required dependencies..."
    
    # Essential packages list
    local PACKAGES=(
        "build-essential"
        "wget"
        "curl"
        "whiptail"
        "tar"
        "gzip"
        "coreutils"
        "ca-certificates"
        "gnupg"
        "apt-transport-https"
    )
    
    # Update package lists (ignore errors)
    apt-get update -qq || true
    
    # Install packages one by one to handle failures gracefully
    for pkg in "${PACKAGES[@]}"; do
        if dpkg -s "$pkg" &>/dev/null; then
            log_success "$pkg is already installed"
        else
            log_info "Installing $pkg..."
            if apt-get install -y "$pkg" &>/dev/null; then
                log_success "$pkg installed successfully"
            else
                log_warning "Failed to install $pkg, continuing..."
            fi
        fi
    done
    
    # GCC - Required for shc compilation
    if command -v gcc &>/dev/null; then
        log_success "gcc is already installed: $(gcc --version | head -n1)"
    else
        log_info "Installing gcc..."
        apt-get install -y gcc
        if command -v gcc &>/dev/null; then
            log_success "gcc installed successfully"
        else
            log_error "gcc installation failed - this may cause issues"
        fi
    fi
    
    # SHC - Shell Script Compiler (optional but recommended)
    if command -v shc &>/dev/null; then
        log_success "shc is already installed"
    else
        log_info "Installing shc..."
        if apt-get install -y shc &>/dev/null; then
            log_success "shc installed successfully"
        else
            log_warning "shc not available in repos, skipping (optional)"
        fi
    fi
    
    log_success "Dependencies installation completed"
}

# ============================================
# Device-Specific Setup
# ============================================
setup_device() {
    local DEVICE=$1
    
    log_info "Running device-specific setup for: $DEVICE"
    
    case "$DEVICE" in
        "meson64")
            setup_smgbox
            ;;
        "raspberrypi")
            setup_raspberry_pi
            ;;
        "tinkerboard")
            setup_tinkerboard
            ;;
        "smglinux"|"smgplayer")
            setup_arm_generic
            ;;
        "x86_64"|"i386"|"i686")
            setup_x86
            ;;
    esac
}

setup_smgbox() {
    log_info "Configuring SMGBox (meson64)..."
    
    # SMGBox specific: Force Debian Bullseye repos
    fix_debian_repos "bullseye"
    
    # Update and upgrade (ignore errors)
    apt-get update || true
    apt-get upgrade -y || true
    
    log_success "SMGBox configuration completed"
}

setup_raspberry_pi() {
    log_info "Configuring Raspberry Pi..."
    
    # Detect Raspbian version
    local VERSION="bullseye"
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        VERSION="${VERSION_CODENAME:-bullseye}"
    fi
    
    fix_raspbian_repos "$VERSION"
    
    # Install RPi specific packages
    apt-get update || true
    apt-get install -y raspi-config || true
    
    log_success "Raspberry Pi configuration completed"
}

setup_tinkerboard() {
    log_info "Configuring Tinkerboard..."
    
    # Tinkerboard usually runs Armbian
    fix_debian_repos "bullseye"
    
    apt-get update || true
    
    log_success "Tinkerboard configuration completed"
}

setup_arm_generic() {
    log_info "Configuring ARM device..."
    
    fix_debian_repos "bullseye"
    apt-get update || true
    
    log_success "ARM device configuration completed"
}

setup_x86() {
    log_info "Configuring x86/x64 device..."
    
    # Detect if Debian or Ubuntu
    local OS_ID=""
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS_ID="$ID"
    fi
    
    if [ "$OS_ID" = "ubuntu" ]; then
        fix_ubuntu_repos
    else
        fix_debian_repos "bullseye"
    fi
    
    apt-get update || true
    
    log_success "x86/x64 device configuration completed"
}

# ============================================
# Hash Verification
# ============================================
check_hash() {
    local file=$1
    
    # Skip hash check if EXPECTED_HASH is empty
    if [ -z "$EXPECTED_HASH" ]; then
        log_warning "Hash check skipped (no expected hash defined)"
        return 0
    fi
    
    log_info "Verifying file integrity..."
    local downloaded_hash=$(sha256sum "$file" | awk '{ print $1 }')

    if [ "$downloaded_hash" != "$EXPECTED_HASH" ]; then
        log_error "Hash verification failed!"
        log_error "Expected: $EXPECTED_HASH"
        log_error "Got: $downloaded_hash"
        exit 1
    fi
    
    log_success "Hash verification passed"
}

# ============================================
# Download and Install
# ============================================
download_and_install() {
    local DEVICE=$1
    
    echo ""
    echo "=========================================="
    echo "  SMG AIO Modular Installation v$VERSION"
    echo "  Device: $DEVICE"
    echo "=========================================="
    echo ""
    
    # Check if already installed
    if [ -d "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/smgaio_modular.sh" ]; then
        log_warning "SMG AIO is already installed at $INSTALL_DIR"
        if ! whiptail --yesno "SMG AIO is already installed. Do you want to reinstall/update?" 8 60; then
            log_info "Installation cancelled by user"
            exit 0
        fi
        log_info "Removing old installation..."
        rm -rf "$INSTALL_DIR"
    fi
    
    # Create installation directory
    mkdir -p "$INSTALL_DIR"
    
    # Download with retry
    cd /tmp
    local MAX_RETRIES=3
    local RETRY=0
    local DOWNLOAD_SUCCESS=false
    
    while [ $RETRY -lt $MAX_RETRIES ] && [ "$DOWNLOAD_SUCCESS" = "false" ]; do
        log_info "Downloading SMG AIO package (attempt $((RETRY+1))/$MAX_RETRIES)..."
        
        if wget -q --show-progress --timeout=30 "$BASEURL/$TARBALL" -O "$TARBALL" 2>&1; then
            if [ -f "$TARBALL" ] && [ -s "$TARBALL" ]; then
                DOWNLOAD_SUCCESS=true
                log_success "Download completed"
            fi
        fi
        
        if [ "$DOWNLOAD_SUCCESS" = "false" ]; then
            RETRY=$((RETRY+1))
            if [ $RETRY -lt $MAX_RETRIES ]; then
                log_warning "Download failed, retrying in 5 seconds..."
                sleep 5
            fi
        fi
    done
    
    if [ "$DOWNLOAD_SUCCESS" = "false" ]; then
        log_error "Download failed after $MAX_RETRIES attempts"
        log_error "Please check your internet connection and try again"
        exit 1
    fi
    
    # Verify hash
    check_hash "$TARBALL"
    
    # Extract to installation directory
    log_info "Extracting to $INSTALL_DIR..."
    tar -xzf "$TARBALL" -C "$INSTALL_DIR" --strip-components=1
    
    if [ $? -ne 0 ]; then
        log_error "Extraction failed"
        exit 1
    fi
    
    # Set permissions
    log_info "Setting permissions..."
    chmod +x "$INSTALL_DIR/smgaio_modular.sh"
    find "$INSTALL_DIR/src" -name "*.sh" -exec chmod +x {} \;
    
    # Create symlink for easy access
    log_info "Creating symlink..."
    mkdir -p /usr/local/bin
    ln -sf "$INSTALL_DIR/smgaio_modular.sh" /usr/local/bin/smgaio
    
    # Cleanup
    rm -f "$TARBALL"
    
    echo ""
    echo "=========================================="
    log_success "Installation Complete!"
    echo "=========================================="
    echo ""
    echo "  Installation path: $INSTALL_DIR"
    echo "  Run with: sudo smgaio"
    echo "  Or: sudo $INSTALL_DIR/smgaio_modular.sh"
    echo ""
    echo "  Log file: $LOG_FILE"
    echo "=========================================="
    echo ""
    
    # Ask to run now
    if whiptail --yesno "Installation complete!\n\nDo you want to run SMG AIO now?" 10 60; then
        exec "$INSTALL_DIR/smgaio_modular.sh"
    fi
}

# ============================================
# Cleanup on Error
# ============================================
cleanup_on_error() {
    log_error "Installation failed!"
    log_info "Cleaning up..."
    rm -f /tmp/"$TARBALL"
    log_info "Check log file for details: $LOG_FILE"
    exit 1
}

# Set trap for cleanup
trap cleanup_on_error ERR

# ============================================
# Main Function
# ============================================
main() {
    # Initialize log
    mkdir -p "$(dirname "$LOG_FILE")"
    echo "" >> "$LOG_FILE"
    log "=========================================="
    log "SMG AIO Installation Started - v$VERSION"
    log "=========================================="
    
    # Check root
    check_root
    
    # Detect device
    log_info "Detecting device..."
    DEVICE=$(detect_device)
    log_success "Device detected: $DEVICE"
    
    # Check network
    check_network
    
    # Fix repositories
    fix_repositories
    
    # Device-specific setup
    setup_device "$DEVICE"
    
    # Install dependencies
    install_dependencies
    
    # Download and install
    download_and_install "$DEVICE"
    
    log "=========================================="
    log "SMG AIO Installation Completed Successfully"
    log "=========================================="
    
    # Self-delete: Remove the downloader script after successful installation
    self_delete
}

# ============================================
# Self Delete Function - STRONG VERSION
# ============================================
self_delete() {
    local SCRIPT_PATH="$(realpath "$0" 2>/dev/null || echo "$0")"
    local SCRIPT_NAME="$(basename "$0")"
    local SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
    
    log_info "=== Self-Delete Check ==="
    log_info "Script path: $SCRIPT_PATH"
    log_info "Install dir: $INSTALL_DIR"
    
    # Step 1: Verify installation exists
    if [ ! -d "$INSTALL_DIR" ]; then
        log_error "Installation directory not found: $INSTALL_DIR"
        log_warning "Keeping installer script for retry"
        return 1
    fi
    
    if [ ! -f "$INSTALL_DIR/smgaio_modular.sh" ]; then
        log_error "Main script not found: $INSTALL_DIR/smgaio_modular.sh"
        log_warning "Keeping installer script for retry"
        return 1
    fi
    
    # Step 2: Verify main script is executable
    if [ ! -x "$INSTALL_DIR/smgaio_modular.sh" ]; then
        chmod +x "$INSTALL_DIR/smgaio_modular.sh" 2>/dev/null
    fi
    
    log_success "Installation verified at $INSTALL_DIR"
    
    # Step 3: Don't delete if running from installed directory
    if [[ "$SCRIPT_PATH" == "$INSTALL_DIR"* ]]; then
        log_info "Running from install directory, not deleting"
        return 0
    fi
    
    # Step 4: Multiple deletion methods for reliability
    log_info "Scheduling installer removal..."
    
    # Method 1: Create a cleanup script that runs after this script exits
    local CLEANUP_SCRIPT="/tmp/.smgaio_cleanup_$$.sh"
    cat > "$CLEANUP_SCRIPT" << CLEANUP_EOF
#!/bin/bash
sleep 3
# Try multiple times
for i in 1 2 3; do
    if [ -f "$SCRIPT_PATH" ]; then
        rm -f "$SCRIPT_PATH" 2>/dev/null
        sync
    fi
    sleep 1
done
# Also check common download locations
rm -f "/tmp/$SCRIPT_NAME" 2>/dev/null
rm -f "/root/$SCRIPT_NAME" 2>/dev/null
rm -f "/home/*/$SCRIPT_NAME" 2>/dev/null
rm -f "\$HOME/$SCRIPT_NAME" 2>/dev/null
# Self-destruct cleanup script
rm -f "$CLEANUP_SCRIPT" 2>/dev/null
CLEANUP_EOF
    
    chmod +x "$CLEANUP_SCRIPT"
    nohup "$CLEANUP_SCRIPT" > /dev/null 2>&1 &
    
    # Method 2: Also use trap to delete on exit
    trap "rm -f '$SCRIPT_PATH' 2>/dev/null; rm -f '$CLEANUP_SCRIPT' 2>/dev/null" EXIT
    
    # Method 3: Background deletion as backup
    (sleep 5 && rm -f "$SCRIPT_PATH" 2>/dev/null) &
    
    log_success "Installer will be removed after exit"
    log_info "Installation complete! Run 'smgaio' to start."
    
    return 0
}

# Run main
main "$@"
