#!/bin/bash
# ==========================================================
# ProxMenux - Shared utility installation functions
# ==========================================================
# Source this file in scripts that need to install system utilities.
# Provides: PROXMENUX_UTILS array, ensure_repositories(), install_single_package()
#
# Usage:
#   source "$LOCAL_SCRIPTS/global/utils-install-functions.sh"
# ==========================================================

# All available utilities — format: "package:verify_command:description"
PROXMENUX_UTILS=(
    "axel:axel:Download accelerator"
    "dos2unix:dos2unix:Convert DOS/Unix text files"
    "grc:grc:Generic log colorizer"
    "htop:htop:Interactive process viewer"
    "btop:btop:Modern resource monitor"
    "iftop:iftop:Real-time network usage"
    "iotop:iotop:Monitor disk I/O usage"
    "iperf3:iperf3:Network bandwidth testing"
    "intel-gpu-tools:intel_gpu_top:Intel GPU tools"
    "s-tui:s-tui:Stress-Terminal UI"
    "ipset:ipset:Manage IP sets"
    "iptraf-ng:iptraf-ng:Network monitoring tool"
    "plocate:locate:Locate files quickly"
    "msr-tools:rdmsr:Access CPU MSRs"
    "net-tools:netstat:Legacy networking tools"
    "sshpass:sshpass:Non-interactive SSH login"
    "tmux:tmux:Terminal multiplexer"
    "unzip:unzip:Extract ZIP files"
    "zip:zip:Create ZIP files"
    "libguestfs-tools:virt-filesystems:VM disk utilities"
    "aria2:aria2c:Multi-source downloader"
    "cabextract:cabextract:Extract CAB files"
    "wimtools:wimlib-imagex:Manage WIM images"
    "genisoimage:genisoimage:Create ISO images"
    "chntpw:chntpw:Edit Windows registry/passwords"
)


# Ensure APT repositories are configured for the current PVE version.
# Creates missing no-subscription repo entries for PVE8 (bookworm) or PVE9 (trixie).
ensure_repositories() {
    local pve_version need_update=false
    pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+' | head -1)

    if [[ -z "$pve_version" ]]; then
        msg_error "Unable to detect Proxmox version."
        return 1
    fi

    if (( pve_version >= 9 )); then
        # ===== PVE 9 (Debian 13 - trixie) =====
        if [[ ! -f /etc/apt/sources.list.d/proxmox.sources ]]; then
            cat > /etc/apt/sources.list.d/proxmox.sources <<'EOF'
Enabled: true
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
            need_update=true
        fi

        if [[ ! -f /etc/apt/sources.list.d/debian.sources ]]; then
            cat > /etc/apt/sources.list.d/debian.sources <<'EOF'
Types: deb
URIs: http://deb.debian.org/debian/
Suites: trixie trixie-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
URIs: http://security.debian.org/debian-security/
Suites: trixie-security
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
            need_update=true
        fi

    else
        # ===== PVE 8 (Debian 12 - bookworm) =====
        local sources_file="/etc/apt/sources.list"

        if ! grep -qE 'deb .* bookworm .* main' "$sources_file" 2>/dev/null; then
            {
                echo "deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware"
                echo "deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware"
                echo "deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware"
            } >> "$sources_file"
            need_update=true
        fi

        if [[ ! -f /etc/apt/sources.list.d/pve-no-subscription.list ]]; then
            echo "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" \
                > /etc/apt/sources.list.d/pve-no-subscription.list
            need_update=true
        fi
    fi

    if [[ "$need_update" == true ]] || [[ ! -d /var/lib/apt/lists || -z "$(ls -A /var/lib/apt/lists 2>/dev/null)" ]]; then
        msg_info "$(translate "Updating APT package lists...")"
        apt-get update >/dev/null 2>&1 || apt-get update
    fi

    return 0
}


# Install a single package and verify the resulting command is available.
# Args: package_name  verify_command  description
# Returns: 0=ok  1=install_failed  2=installed_but_command_not_found
install_single_package() {
    local package="$1"
    local command_name="${2:-$package}"
    local description="${3:-$package}"

    msg_info "$(translate "Installing") $package${description:+ ($description)}..."
    local install_success=false

    if DEBIAN_FRONTEND=noninteractive apt-get install -y "$package" >/dev/null 2>&1; then
        install_success=true
    fi
    cleanup 2>/dev/null || true

    if [[ "$install_success" == true ]]; then
        hash -r 2>/dev/null
        sleep 1
        if command -v "$command_name" >/dev/null 2>&1; then
            msg_ok "$package $(translate "installed correctly and available")"
            return 0
        else
            msg_warn "$package $(translate "installed but command not immediately available")"
            msg_info2 "$(translate "May need to restart terminal")"
            return 2
        fi
    else
        msg_error "$(translate "Error installing") $package"
        return 1
    fi
}
