#\!/bin/bash

# Kivy Signage Player Installation Script
# Supports both online and offline installation using a Python virtual environment
#
# Usage:
#   bash install.sh [OPTIONS]
#
# Options:
#   -U, --sudo-user USER     Username for sudo (avoids password prompts)
#   -W, --sudo-password PASS Password for sudo (use with caution)
#   --offline                Force offline installation from local packages
#   -q, --quiet              Silent mode
#   -h, --help               Show help
#
# Configuration options (for Digiserver):
#   -s, --server IP          Server IP/hostname
#   -p, --port PORT          Server port (default: 8080)
#   -n, --name NAME          Screen/player name
#   -k, --key KEY            Quick-connect / auth key
#   --https                  Enable HTTPS
#   --no-verify-ssl          Disable SSL verification
#   -o, --orientation        Landscape or Portrait
#   --touch                  Enable touch input
#   -r, --resolution WxH     Max resolution
#   --edit                   Enable on-device edit feature
#   --provision URL          One-time provisioning URL
#   --config FILE            Path to pre-made JSON config

set -e

# ============================================================
# Configuration
# ============================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$SCRIPT_DIR/repo"
WHEELS_DIR="$REPO_DIR/python-wheels"
SYSTEM_DIR="$REPO_DIR/system-packages"
DEB_DIR="$SYSTEM_DIR/debs"
VENV_DIR="$SCRIPT_DIR/.venv"
REQUIREMENTS_FILE="$SCRIPT_DIR/requirements.txt"
SUDO_USERNAME=""
SUDO_PASSWORD=""
OFFLINE_MODE=false
PI_BOOT_PATCH_SCRIPT="$SCRIPT_DIR/scripts/pi_boot_config_patch_once.sh"

# ============================================================
# Helper: Run sudo with optional password
# ============================================================
run_sudo() {
    if [ -n "$SUDO_PASSWORD" ]; then
        echo "$SUDO_PASSWORD" | sudo -S "$@" 2>/dev/null
    else
        sudo "$@"
    fi
}

# ============================================================
# Helpers
# ============================================================
find_boot_config() {
    if [ -f /boot/firmware/config.txt ]; then
        echo "/boot/firmware/config.txt"
    elif [ -f /boot/config.txt ]; then
        echo "/boot/config.txt"
    else
        echo ""
    fi
}

detect_raspberry_pi() {
    BOOT_CONFIG=$(find_boot_config)
    if grep -qi "raspberry" /proc/cpuinfo 2>/dev/null || [ -n "$BOOT_CONFIG" ]; then
        return 0
    else
        return 1
    fi
}

# ============================================================
# CLI Argument Parsing
# ============================================================
SERVER_IP=""
SERVER_PORT=""
SCREEN_NAME=""
QUICKCONNECT_KEY=""
USE_HTTPS=""
VERIFY_SSL=""
ORIENTATION=""
TOUCH_ENABLED=""
MAX_RESOLUTION=""
EDIT_ENABLED=""
PROVISION_URL=""
CONFIG_FILE_PATH=""

usage() {
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Authentication options (avoids sudo password prompts):"
    echo "  -U, --sudo-user USER     Username for sudo commands"
    echo "  -W, --sudo-password PASS Password for sudo commands"
    echo ""
    echo "Installation modes (choose one):"
    echo "  --provision URL   One-time provisioning URL from Digiserver"
    echo "  --config FILE     Path to pre-made JSON config file"
    echo "  (individual params)  Set each config value manually"
    echo ""
    echo "Configuration options:"
    echo "  -s, --server IP      Digiserver IP or hostname"
    echo "  -p, --port PORT      Server port (default: 8080)"
    echo "  -n, --name NAME      Screen/player name"
    echo "  -k, --key KEY        Quick-connect / auth key"
    echo "      --https          Enable HTTPS for server communication"
    echo "      --no-verify-ssl  Disable SSL certificate verification"
    echo "  -o, --orientation    Landscape or Portrait (default: Landscape)"
    echo "      --touch          Enable touch input"
    echo "  -r, --resolution WxH Max resolution (default: 1920x1080)"
    echo "      --edit           Enable on-device edit feature"
    echo ""
    echo "Installation options:"
    echo "      --offline        Force offline installation from local packages"
    echo "  -q, --quiet          Silent mode (minimal output)"
    echo "  -h, --help           Show this help"
    exit 0
}

while [ $# -gt 0 ]; do
    case "$1" in
        -U|--sudo-user)
            SUDO_USERNAME="$2"
            shift 2
            ;;
        -W|--sudo-password)
            SUDO_PASSWORD="$2"
            shift 2
            ;;
        --provision)
            PROVISION_URL="$2"
            shift 2
            ;;
        --config)
            CONFIG_FILE_PATH="$2"
            shift 2
            ;;
        -s|--server)
            SERVER_IP="$2"
            shift 2
            ;;
        -p|--port)
            SERVER_PORT="$2"
            shift 2
            ;;
        -n|--name)
            SCREEN_NAME="$2"
            shift 2
            ;;
        -k|--key)
            QUICKCONNECT_KEY="$2"
            shift 2
            ;;
        --https)
            USE_HTTPS="true"
            shift
            ;;
        --no-verify-ssl)
            VERIFY_SSL="false"
            shift
            ;;
        -o|--orientation)
            ORIENTATION="$2"
            shift 2
            ;;
        --touch)
            TOUCH_ENABLED="True"
            shift
            ;;
        -r|--resolution)
            MAX_RESOLUTION="$2"
            shift 2
            ;;
        --edit)
            EDIT_ENABLED="true"
            shift
            ;;
        --offline)
            OFFLINE_MODE=true
            shift
            ;;
        -q|--quiet)
            exec > >(tee -a /tmp/kivy-install.log) 2>&1
            shift
            ;;
        -h|--help)
            usage
            ;;
        *)
            echo "Unknown option: $1"
            usage
            ;;
    esac
done

# Auto-detect offline mode if wheels exist
if [ "$OFFLINE_MODE" = false ] && [ -d "$WHEELS_DIR" ] && [ "$(ls -A "$WHEELS_DIR"/*.whl 2>/dev/null)" ]; then
    OFFLINE_MODE=true
fi

# ============================================================
# Mode Banner
# ============================================================
echo "=========================================="
echo "Kivy Signage Player v1.2.0 - Installer"
echo "=========================================="
if [ "$OFFLINE_MODE" = true ]; then
    echo "Mode: Offline Installation"
else
    echo "Mode: Online Installation"
fi
if [ -n "$SUDO_USERNAME" ]; then
    echo "Sudo user: $SUDO_USERNAME"
fi
echo ""

# ============================================================
# Step 1: System Dependencies
# ============================================================
echo "Step 1/6: Installing system dependencies..."
echo "--------------------"

echo "Updating package lists..."
run_sudo apt update

echo "Installing system packages..."

if [ "$OFFLINE_MODE" = true ] && [ -d "$DEB_DIR" ] && [ "$(ls -A $DEB_DIR/*.deb 2>/dev/null)" ]; then
    echo "Installing from offline .deb packages..."
    cd "$DEB_DIR"
    run_sudo dpkg -i *.deb 2>/dev/null || true
    run_sudo apt-get install -f -y || true
    cd "$SCRIPT_DIR"
fi

run_sudo apt install -y \
    python3-pip python3-setuptools python3-dev \
    python3-venv \
    libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev \
    libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev \
    zlib1g-dev ffmpeg libavcodec-extra \
    gstreamer1.0-plugins-base gstreamer1.0-plugins-good

echo "System dependencies installed"
echo ""

# ============================================================
# Step 2: Python Virtual Environment
# ============================================================
echo "Step 2/6: Setting up Python virtual environment..."
echo "--------------------"

if [ -d "$VENV_DIR" ]; then
    echo "Removing old virtual environment..."
    rm -rf "$VENV_DIR"
fi

echo "Creating virtual environment (with system site-packages)..."
python3 -m venv --system-site-packages "$VENV_DIR"
echo "Virtual environment created at $VENV_DIR"

source "$VENV_DIR/bin/activate"

echo "Upgrading pip..."
pip install --upgrade pip --quiet

echo ""

# ============================================================
# Step 3: Install Python Packages
# ============================================================
echo "Step 3/6: Installing Python packages..."
echo "--------------------"

PIP_EXTRA_ARGS=""
if [ "$OFFLINE_MODE" = true ]; then
    echo "Using offline wheel repository: $WHEELS_DIR"
    PIP_EXTRA_ARGS="--no-index --find-links=$WHEELS_DIR"
fi

if [ -f "$REQUIREMENTS_FILE" ]; then
    echo "Installing packages from requirements.txt..."
    if [ "$OFFLINE_MODE" = true ]; then
        if pip install $PIP_EXTRA_ARGS -r "$REQUIREMENTS_FILE"; then
            echo "All packages installed from offline repository"
        else
            echo ""
            echo "Offline installation failed (some wheels may be missing or incompatible)"
            echo "  Falling back to online installation (requires internet)..."
            echo ""
            pip install -r "$REQUIREMENTS_FILE" --find-links="$WHEELS_DIR" 2>&1 || true
        fi
    else
        pip install -r "$REQUIREMENTS_FILE" --find-links="$WHEELS_DIR" 2>&1 || true
    fi
    
    # Verify critical packages are importable
    echo ""
    echo "Verifying installed packages..."
    pip list --format=columns 2>/dev/null | grep -iE "kivy|ffpyplayer" || true
    
    # If kivy is still missing after pip install, try system-wide fallback
    python3 -c "import kivy" 2>/dev/null && echo "  kivy OK" || {
        echo ""
        echo "  kivy not found in venv — installing system-wide via pip (break-system-packages)..."
        pip install kivy --break-system-packages 2>/dev/null || pip install --user kivy 2>/dev/null || true
    }
    python3 -c "import ffpyplayer" 2>/dev/null && echo "  ffpyplayer OK" || {
        echo "  ffpyplayer not found — installing system-wide..."
        pip install ffpyplayer --break-system-packages 2>/dev/null || pip install --user ffpyplayer 2>/dev/null || true
    }
else
    echo "requirements.txt not found - skipping pip install"
fi

echo ""

deactivate

# ============================================================
# Step 4: Autostart Workflow
# ============================================================
echo "Step 4/6: Setting up autostart..."
echo "--------------------"

ACTUAL_USER="${SUDO_USERNAME:-${SUDO_USER:-$(whoami)}}"
ACTUAL_HOME=$(eval echo ~"$ACTUAL_USER")
AUTOSTART_DIR="$ACTUAL_HOME/.config/autostart"

echo "Configuring autostart for user: $ACTUAL_USER"

mkdir -p "$AUTOSTART_DIR"
cat > "$AUTOSTART_DIR/kivy-signage-player.desktop" << EOF
[Desktop Entry]
Type=Application
Name=Kivy Signage Player
Comment=Digital Signage Player
Exec=/bin/bash -c "cd $SCRIPT_DIR && exec bash start.sh"
Icon=media-video-display
Categories=Utility;
NoDisplay=false
Terminal=false
StartupNotify=false
Hidden=false
X-GNOME-Autostart-enabled=true
X-GNOME-Autostart-delay=3
X-XFCE-Autostart-Override=true
EOF

run_sudo chown "$ACTUAL_USER:$ACTUAL_USER" "$AUTOSTART_DIR/kivy-signage-player.desktop" 2>/dev/null || true
chmod 644 "$AUTOSTART_DIR/kivy-signage-player.desktop" 2>/dev/null || true
echo "XDG autostart entry created"

# Cron fallback
if command -v crontab &>/dev/null; then
    CRON_WRAPPER="$SCRIPT_DIR/.start-player-cron.sh"
    cat > "$CRON_WRAPPER" << EOF
#\!/bin/bash
sleep 15
cd $SCRIPT_DIR && bash start.sh
EOF
    chmod +x "$CRON_WRAPPER"
    
    CRON_ENTRY="@reboot sleep 20 && $CRON_WRAPPER > /tmp/kivy-player-cron.log 2>&1"
    # Use sudo -u which works when running with sudo (no password prompt)
    if sudo -u "$ACTUAL_USER" crontab -l 2>/dev/null | grep -q "kivy-signage-player"; then
        true
    else
        (sudo -u "$ACTUAL_USER" crontab -l 2>/dev/null || true; echo "$CRON_ENTRY") | sudo -u "$ACTUAL_USER" crontab - 2>/dev/null || true
    fi
    echo "Cron fallback configured"
fi

echo ""

# ============================================================
# Step 5: Raspberry Pi Optimization
# ============================================================
if detect_raspberry_pi; then
    echo "Step 5/6: Optimizing for Raspberry Pi..."
    echo "--------------------"
    
    BOOT_CONFIG=$(find_boot_config)
    if [ -n "$BOOT_CONFIG" ]; then
        echo "Configuring HDMI settings..."
        for setting in "hdmi_blanking=0" "hdmi_ignore_cec_init=1" "hdmi_force_hotplug=1"; do
            key="${setting%%=*}"
            if grep -q "^$key" "$BOOT_CONFIG" 2>/dev/null; then
                run_sudo sed -i "s/^$key=.*/$setting/" "$BOOT_CONFIG"
            else
                echo "$setting" | run_sudo tee -a "$BOOT_CONFIG" > /dev/null
            fi
        done
        echo "HDMI settings configured"
    fi
    
    echo "Setting CPU to performance mode..."
    for cpu in /sys/devices/system/cpu/cpu[0-9]*; do
        if [ -f "$cpu/cpufreq/scaling_governor" ]; then
            echo performance | run_sudo tee "$cpu/cpufreq/scaling_governor" > /dev/null 2>&1 || true
        fi
    done
    
    run_sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target 2>/dev/null || true
    echo "System sleep disabled"
    
    if [ -f "$SCRIPT_DIR/.video-optimization.sh" ]; then
        bash "$SCRIPT_DIR/.video-optimization.sh"
    fi
    
    echo ""
fi

# ============================================================
# Step 6: Finalize Player Setup
# ============================================================
echo "Step 6/6: Finalizing player setup..."
echo "--------------------"

# Create required directories
echo "Creating player directories..."
mkdir -p "$SCRIPT_DIR/media"
mkdir -p "$SCRIPT_DIR/playlists"
mkdir -p "$SCRIPT_DIR/config/resources"
mkdir -p "$SCRIPT_DIR/logs"
touch "$SCRIPT_DIR/logs/.gitkeep" 2>/dev/null || true
echo "Player directories created"

# Write player configuration
write_player_config() {
    local config_dir="$SCRIPT_DIR/config"
    local config_file="$config_dir/app_config.json"
    mkdir -p "$config_dir"
    
    if [ -n "$PROVISION_URL" ]; then
        echo "Fetching provisioning data from: $PROVISION_URL"
        local response
        response=$(curl -sSf "$PROVISION_URL" 2>&1 || true)
        if [ -n "$response" ]; then
            echo "$response" > "$config_file"
            echo "Provisioning data saved"
            return 0
        fi
        echo "Failed to fetch provisioning data"
    fi
    
    if [ -n "$CONFIG_FILE_PATH" ] && [ -f "$CONFIG_FILE_PATH" ]; then
        cp "$CONFIG_FILE_PATH" "$config_file"
        echo "Configuration copied from $CONFIG_FILE_PATH"
        return 0
    fi
    
    if [ -n "$SERVER_IP" ] || [ -n "$SCREEN_NAME" ] || [ -n "$QUICKCONNECT_KEY" ]; then
        export SERVER_IP SERVER_PORT SCREEN_NAME QUICKCONNECT_KEY
        export ORIENTATION TOUCH_ENABLED MAX_RESOLUTION
        export USE_HTTPS VERIFY_SSL EDIT_ENABLED
        
        python3 << PYEOF
import json, os

config_file = "$config_file"
config = {}
if os.path.exists(config_file):
    with open(config_file) as f:
        config = json.load(f)

cli_params = {
    'server_ip': os.environ.get('SERVER_IP', ''),
    'port': os.environ.get('SERVER_PORT', ''),
    'screen_name': os.environ.get('SCREEN_NAME', ''),
    'quickconnect_key': os.environ.get('QUICKCONNECT_KEY', ''),
    'orientation': os.environ.get('ORIENTATION', ''),
    'touch': os.environ.get('TOUCH_ENABLED', ''),
    'max_resolution': os.environ.get('MAX_RESOLUTION', ''),
}

for key, val in cli_params.items():
    if val:
        config[key] = val

https_val = os.environ.get('USE_HTTPS', '')
verify_val = os.environ.get('VERIFY_SSL', '')
edit_val = os.environ.get('EDIT_ENABLED', '')

if https_val:
    config['use_https'] = https_val.lower() == 'true'
if verify_val:
    config['verify_ssl'] = verify_val.lower() == 'false'
if edit_val:
    config['edit_feature_enabled'] = edit_val.lower() == 'true'

config.setdefault('port', '8080')
config.setdefault('orientation', 'Landscape')
config.setdefault('touch', 'True')
config.setdefault('max_resolution', '1920x1080')
config.setdefault('edit_feature_enabled', False)
config.setdefault('use_https', False)
config.setdefault('verify_ssl', True)

with open(config_file, 'w') as f:
    json.dump(config, f, indent=2)

print("Configuration written")
PYEOF
    elif [ \! -f "$config_file" ]; then
        cat > "$config_file" << 'EOF'
{
  "server_ip": "",
  "port": "8080",
  "screen_name": "",
  "quickconnect_key": "",
  "orientation": "Landscape",
  "touch": "True",
  "max_resolution": "1920x1080",
  "edit_feature_enabled": false,
  "use_https": false,
  "verify_ssl": true
}
EOF
        echo "Default config template created"
    fi
}
write_player_config

# Initialize authentication
config_file="$SCRIPT_DIR/config/app_config.json"
if [ -f "$config_file" ]; then
    if python3 -c "
import json
c = json.load(open('$config_file'))
if c.get('server_ip') and c.get('screen_name') and c.get('quickconnect_key'):
    exit(0)
else:
    exit(1)
" 2>/dev/null; then
        echo "Attempting player registration..."
        cd "$SCRIPT_DIR/src"
        source "$VENV_DIR/bin/activate"
        python3 -c "
import json, sys
sys.path.insert(0, '.')
from get_playlists_v2 import ensure_authenticated

with open('$config_file') as f:
    config = json.load(f)

auth = ensure_authenticated(config)
if auth:
    print('Player registered successfully')
    sys.exit(0)
else:
    print('Registration deferred')
    sys.exit(1)
" 2>&1 || echo "Auth initialization deferred"
        deactivate 2>/dev/null || true
        cd "$SCRIPT_DIR"
    else
        echo "Incomplete config - auth will happen on first run"
    fi
fi

# Create background runner
NOHUP_WRAPPER="$SCRIPT_DIR/.run-background.sh"
cat > "$NOHUP_WRAPPER" << EOF
#\!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="$SCRIPT_DIR/logs/player-background.log"
mkdir -p "$(dirname "$LOG_FILE")"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting player in background..." >> "$LOG_FILE"
cd "$SCRIPT_DIR" || exit 1
nohup bash start.sh >> "$LOG_FILE" 2>&1 &
PLAYER_PID=\$\!
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Player started with PID: \$PLAYER_PID" >> "$LOG_FILE"
echo "Player started in background (PID: \$PLAYER_PID)"
echo "Logs: \$LOG_FILE"
EOF
chmod +x "$NOHUP_WRAPPER"
echo "Background runner created"

# ============================================================
# Final Summary
# ============================================================
echo ""
echo "=========================================="
echo "Installation Complete\!"
echo "=========================================="
echo ""
echo "Installation: $SCRIPT_DIR"
echo "Virtual Env:   $VENV_DIR"
echo ""

if [ -f "$SCRIPT_DIR/config/app_config.json" ]; then
    echo "Player Configuration:"
    echo "------------------------"
    python3 -c "
import json
with open('$SCRIPT_DIR/config/app_config.json') as f:
    c = json.load(f)
print(f'  Server:     {c.get(\"server_ip\",\"not set\")}')
print(f'  Port:       {c.get(\"port\",\"8080\")}')
print(f'  Screen:     {c.get(\"screen_name\",\"not set\")}')
print(f'  HTTPS:      {c.get(\"use_https\",False)}')
print(f'  Resolution: {c.get(\"max_resolution\",\"auto\")}')
" 2>/dev/null || echo "  (config present)"
    echo ""
fi

echo "Quick Start Commands:"
echo "------------------------"
echo "  bash start.sh                 Start with watchdog (auto-restart)"
echo "  bash run_player.sh            Run once (no auto-restart)"
echo "  bash .run-background.sh       Run in background"
echo "  bash check_player_status.sh   Check player status"
echo "  bash stop_player.sh           Stop the player"
echo ""
echo "Autostart enabled for user: $ACTUAL_USER"
echo ""
echo "Logs: $SCRIPT_DIR/logs/"
echo ""

if [ -f "$PI_BOOT_PATCH_SCRIPT" ]; then
    echo "Applying one-time Raspberry Pi boot config patch..."
    run_sudo chmod +x "$PI_BOOT_PATCH_SCRIPT" 2>/dev/null || true
    if run_sudo bash "$PI_BOOT_PATCH_SCRIPT"; then
        echo "One-time boot patch applied (or already present)"
    else
        echo "Boot patch skipped or failed; continuing installation"
    fi
    echo ""
fi

if [ -z "$SUDO_PASSWORD" ]; then
    echo "=========================================="
    echo "System Reboot Recommended"
    echo "=========================================="
    echo ""
    echo "Some changes (HDMI settings, GPU memory) require a reboot."
    echo ""
    echo "Rebooting in 5 seconds... Press Ctrl+C to cancel."
    sleep 5
    echo "Rebooting now..."
    run_sudo reboot
fi
