#!/bin/bash

#############################################################################
# OS Compatibility Check Module
# Verifies OS-specific packages, compatibility, and version requirements
# Supports: CentOS, AlmaLinux, Rocky, CloudLinux, Ubuntu, Debian
#############################################################################

set -eo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
LIB_DIR="$BASE_DIR/lib"

# Load libraries
source "$LIB_DIR/common-functions.sh"
source "$LIB_DIR/system-detect.sh"

# Ensure system detection is complete
[ -z "${SYS_DETECTION_COMPLETE:-}" ] && initialize_system_detection

#############################################################################
# COLORS & FORMATTING
#############################################################################

PASS="${GREEN}✓${NC}"
FAIL="${RED}✗${NC}"
WARN="${YELLOW}⚠${NC}"
INFO="${CYAN}ℹ${NC}"

#############################################################################
# PACKAGE CHECK FUNCTIONS
#############################################################################

package_installed() {
    local package="$1"

    case "$SYS_OS_TYPE" in
        centos|rhel|almalinux|rocky|cloudlinux)
            rpm -q "$package" > /dev/null 2>&1
            ;;
        ubuntu|debian)
            dpkg -l | grep -q "^ii.*$package" || apt list --installed 2>/dev/null | grep -q "^$package/"
            ;;
        *)
            return 1
            ;;
    esac
}

check_package() {
    local package="$1"
    local critical="${2:-0}"

    if package_installed "$package"; then
        local version=$(get_package_version "$package")
        echo "$PASS Package ${GREEN}${package}${NC} is installed (${version})"
        return 0
    else
        if [ "$critical" = "1" ]; then
            echo "$FAIL Package ${RED}${package}${NC} is ${RED}MISSING${NC} (required)"
        else
            echo "$WARN Package ${YELLOW}${package}${NC} is not installed"
        fi
        return 1
    fi
}

get_package_version() {
    local package="$1"

    case "$SYS_OS_TYPE" in
        centos|rhel|almalinux|rocky|cloudlinux)
            rpm -q "$package" 2>/dev/null | sed "s/^${package}-//" || echo "unknown"
            ;;
        ubuntu|debian)
            apt list --installed 2>/dev/null | grep "^${package}/" | awk '{print $2}' | head -1 || echo "unknown"
            ;;
    esac
}

#############################################################################
# RHEL-BASED OS CHECKS
#############################################################################

check_rhel_packages() {
    echo ""
    print_section "RHEL/CentOS Package Compatibility"
    echo ""

    # Essential packages
    check_package "gcc" 1
    check_package "curl" 1
    check_package "wget" 1
    check_package "git" 0

    # Web server
    if [ "$SYS_WEB_SERVER" = "apache" ]; then
        check_package "httpd" 1
    elif [ "$SYS_WEB_SERVER" = "nginx" ]; then
        check_package "nginx" 1
    fi

    # Database
    if [ "$SYS_DB_TYPE" = "mysql" ]; then
        check_package "mysql-server" 0 || check_package "mysql" 0
    elif [ "$SYS_DB_TYPE" = "mariadb" ]; then
        check_package "mariadb-server" 1
    fi

    # PHP
    if [ ${#SYS_PHP_VERSIONS[@]} -gt 0 ]; then
        check_package "php-cli" 0
        check_package "php-common" 0
    fi

    # Additional tools
    check_package "net-tools" 0
    check_package "bind-utils" 0
    check_package "openssh-server" 1

    echo ""
}

#############################################################################
# DEBIAN-BASED OS CHECKS
#############################################################################

check_debian_packages() {
    echo ""
    print_section "Debian/Ubuntu Package Compatibility"
    echo ""

    # Essential packages
    check_package "build-essential" 1
    check_package "curl" 1
    check_package "wget" 1
    check_package "git" 0

    # Web server
    if [ "$SYS_WEB_SERVER" = "apache" ]; then
        check_package "apache2" 1
    elif [ "$SYS_WEB_SERVER" = "nginx" ]; then
        check_package "nginx" 1
    fi

    # Database
    if [ "$SYS_DB_TYPE" = "mysql" ]; then
        check_package "mysql-server" 1
    elif [ "$SYS_DB_TYPE" = "mariadb" ]; then
        check_package "mariadb-server" 1
    fi

    # PHP
    if [ ${#SYS_PHP_VERSIONS[@]} -gt 0 ]; then
        check_package "php-cli" 0
        check_package "php-common" 0
    fi

    # Additional tools
    check_package "net-tools" 0
    check_package "dnsutils" 0
    check_package "openssh-server" 1

    echo ""
}

#############################################################################
# CLOUDLINUX-SPECIFIC CHECKS
#############################################################################

check_cloudlinux_packages() {
    if [ "${SYS_CLOUDLINUX:-}" != "yes" ]; then
        return
    fi

    echo ""
    print_section "CloudLinux-Specific Packages"
    echo ""

    check_package "lve-utils" 0
    check_package "lvemanager" 0
    check_package "kernel-lve" 0
    check_package "cloudlinux-ssa" 0
    check_package "cloudlinux-admin" 0

    # LVE CLI tool
    if command_exists lvectl; then
        echo "$PASS lvectl CLI is available"
    else
        echo "$WARN lvectl command not found (LVE management may be unavailable)"
    fi

    # Check LVE status
    if systemctl is-active --quiet lve-manager 2>/dev/null; then
        echo "$PASS LVE Manager service is running"
    else
        echo "$WARN LVE Manager service is not running"
    fi

    echo ""
}

#############################################################################
# CONTROL PANEL-SPECIFIC CHECKS
#############################################################################

check_cpanel_packages() {
    if [ "$SYS_CONTROL_PANEL" != "cpanel" ]; then
        return
    fi

    echo ""
    print_section "cPanel Package Dependencies"
    echo ""

    # cPanel requires RHEL-based
    if [[ ! "$SYS_OS_TYPE" =~ (centos|rhel|almalinux|rocky|cloudlinux) ]]; then
        echo "$FAIL cPanel requires RHEL-based OS, found: ${RED}${SYS_OS_TYPE}${NC}"
        return 1
    fi

    check_package "cpanel-liveupdate-exclude" 0
    check_package "ea-apache24" 0
    check_package "ea-php" 0

    # cPanel version compatibility
    local major_version=$(echo "$SYS_CONTROL_PANEL_VERSION" | cut -d. -f1)
    if [ "$major_version" -lt 11 ]; then
        echo "$FAIL cPanel version ${RED}${SYS_CONTROL_PANEL_VERSION}${NC} is out of support"
    else
        echo "$PASS cPanel version ${SYS_CONTROL_PANEL_VERSION} is supported"
    fi

    echo ""
}

check_plesk_packages() {
    if [ "$SYS_CONTROL_PANEL" != "plesk" ]; then
        return
    fi

    echo ""
    print_section "Plesk Package Dependencies"
    echo ""

    # Plesk version compatibility
    local major_version=$(echo "$SYS_CONTROL_PANEL_VERSION" | cut -d. -f1)

    if [ "$major_version" -lt 12 ]; then
        echo "$FAIL Plesk version ${RED}${SYS_CONTROL_PANEL_VERSION}${NC} is out of support"
    elif [ "$major_version" -lt 18 ]; then
        echo "$WARN Plesk version ${YELLOW}${SYS_CONTROL_PANEL_VERSION}${NC} is nearing end of support"
    else
        echo "$PASS Plesk version ${GREEN}${SYS_CONTROL_PANEL_VERSION}${NC} is supported"
    fi

    # Plesk requires specific packages
    if [[ "$SYS_OS_TYPE" =~ (ubuntu|debian) ]]; then
        check_package "plesk-core" 0
    elif [[ "$SYS_OS_TYPE" =~ (centos|rhel|almalinux|rocky) ]]; then
        check_package "psa" 0
    fi

    echo ""
}

check_interworx_packages() {
    if [ "$SYS_CONTROL_PANEL" != "interworx" ]; then
        return
    fi

    echo ""
    print_section "InterWorx Package Dependencies"
    echo ""

    if [ -d "/opt/interworx" ]; then
        echo "$PASS InterWorx installation directory found"
    else
        echo "$FAIL InterWorx installation directory ${RED}not found${NC}"
    fi

    # InterWorx uses standard packages
    check_package "openssl" 1
    check_package "perl" 0

    echo ""
}

#############################################################################
# OS VERSION COMPATIBILITY
#############################################################################

check_os_version_support() {
    echo ""
    print_section "OS Version Support Status"
    echo ""

    case "$SYS_OS_TYPE" in
        centos)
            case "$SYS_OS_VERSION" in
                7) echo "$WARN CentOS 7 is ${YELLOW}End of Life (June 2024)${NC}" ;;
                8) echo "$WARN CentOS 8 is ${YELLOW}End of Life (December 2021)${NC}" ;;
                9) echo "$PASS CentOS 9 is ${GREEN}supported until 2032${NC}" ;;
                *) echo "$INFO CentOS $SYS_OS_VERSION version support unknown" ;;
            esac
            ;;
        rhel)
            case "$SYS_OS_VERSION" in
                7) echo "$WARN RHEL 7 is in ${YELLOW}limited support${NC}" ;;
                8) echo "$PASS RHEL 8 is in ${GREEN}standard support${NC}" ;;
                9) echo "$PASS RHEL 9 is in ${GREEN}standard support${NC}" ;;
                *) echo "$INFO RHEL $SYS_OS_VERSION version support unknown" ;;
            esac
            ;;
        almalinux|rocky)
            case "$SYS_OS_VERSION" in
                8) echo "$PASS ${SYS_OS_TYPE^^} 8 is supported until 2029" ;;
                9) echo "$PASS ${SYS_OS_TYPE^^} 9 is supported until 2032" ;;
                *) echo "$INFO ${SYS_OS_TYPE^^} $SYS_OS_VERSION version support unknown" ;;
            esac
            ;;
        cloudlinux)
            case "$SYS_OS_VERSION" in
                7) echo "$WARN CloudLinux 7 is in ${YELLOW}extended support${NC}" ;;
                8|9) echo "$PASS CloudLinux $SYS_OS_VERSION is ${GREEN}fully supported${NC}" ;;
                *) echo "$INFO CloudLinux $SYS_OS_VERSION version support unknown" ;;
            esac
            ;;
        ubuntu)
            case "$SYS_OS_VERSION" in
                20.04) echo "$PASS Ubuntu 20.04 LTS supported until 2030" ;;
                22.04) echo "$PASS Ubuntu 22.04 LTS supported until 2032" ;;
                24.04) echo "$PASS Ubuntu 24.04 LTS supported until 2034" ;;
                *) echo "$INFO Ubuntu $SYS_OS_VERSION support status unknown" ;;
            esac
            ;;
        debian)
            case "$SYS_OS_VERSION" in
                11) echo "$PASS Debian 11 supported until 2026" ;;
                12) echo "$PASS Debian 12 supported until 2028" ;;
                *) echo "$INFO Debian $SYS_OS_VERSION support status unknown" ;;
            esac
            ;;
    esac

    echo ""
}

#############################################################################
# KERNEL & SYSTEM COMPATIBILITY
#############################################################################

check_kernel_compatibility() {
    echo ""
    print_section "Kernel & System Compatibility"
    echo ""

    local kernel=$(uname -r)
    echo "$INFO Kernel version: $kernel"

    # Check for kernel modules
    if [ -f /proc/sys/kernel/osrelease ]; then
        local kernel_release=$(cat /proc/sys/kernel/osrelease)
        echo "$INFO Kernel release: $kernel_release"
    fi

    # Check virtualization/container
    if grep -qi "hypervisor" /proc/cpuinfo 2>/dev/null; then
        echo "$INFO Running in virtualized environment"
    fi

    # Check for known incompatibilities
    case "$SYS_OS_TYPE" in
        centos)
            if [ "$SYS_OS_VERSION" = "8" ] && [ "$SYS_CONTROL_PANEL" = "cpanel" ]; then
                echo "$WARN CentOS 8 with cPanel requires migration path (CentOS Stream)"
            fi
            ;;
    esac

    echo ""
}

#############################################################################
# PACKAGE MANAGER COMPATIBILITY
#############################################################################

check_package_manager() {
    echo ""
    print_section "Package Manager Status"
    echo ""

    case "$SYS_OS_TYPE" in
        centos|rhel|almalinux|rocky|cloudlinux)
            if command_exists yum; then
                echo "$PASS YUM package manager is available"
            elif command_exists dnf; then
                echo "$PASS DNF package manager is available"
            else
                echo "$FAIL No package manager found"
            fi

            # Check for yum plugin conflicts
            if [ -f /etc/yum.repos.d/epel.repo ]; then
                echo "$PASS EPEL repository is configured"
            fi

            # Check for remi repository (optional but common)
            if [ -f /etc/yum.repos.d/remi.repo ]; then
                echo "$INFO Remi repository is configured (for additional PHP versions)"
            fi
            ;;

        ubuntu|debian)
            if command_exists apt; then
                echo "$PASS APT package manager is available"
            else
                echo "$FAIL APT package manager not found"
            fi

            # Check for PPA repositories
            if [ -d /etc/apt/sources.list.d ]; then
                local ppa_count=$(ls /etc/apt/sources.list.d/*.list 2>/dev/null | wc -l)
                if [ "$ppa_count" -gt 0 ]; then
                    echo "$INFO $ppa_count PPA/custom repositories configured"
                fi
            fi

            # Check for Ondrej PPA (PHP)
            if grep -q "ondrej/php" /etc/apt/sources.list* 2>/dev/null; then
                echo "$INFO Ondrej PPA configured (for PHP versions)"
            fi
            ;;
    esac

    echo ""
}

#############################################################################
# CONTROL PANEL / OS COMPATIBILITY MATRIX
#############################################################################

check_panel_os_compatibility() {
    echo ""
    print_section "Control Panel & OS Compatibility"
    echo ""

    local compatible="1"

    case "$SYS_CONTROL_PANEL" in
        cpanel)
            if [[ ! "$SYS_OS_TYPE" =~ (centos|rhel|almalinux|rocky|cloudlinux) ]]; then
                echo "$FAIL cPanel requires RHEL-based OS, but found: ${RED}${SYS_OS_TYPE}${NC}"
                compatible="0"
            else
                echo "$PASS cPanel on ${SYS_OS_TYPE^^} is a ${GREEN}supported configuration${NC}"
            fi
            ;;

        plesk)
            if [[ "$SYS_OS_TYPE" =~ (ubuntu|debian|centos|rhel|almalinux|rocky) ]]; then
                echo "$PASS Plesk on ${SYS_OS_TYPE^^} is a ${GREEN}supported configuration${NC}"
            else
                echo "$FAIL Plesk on ${SYS_OS_TYPE^^} may not be officially supported"
                compatible="0"
            fi
            ;;

        interworx)
            if [[ ! "$SYS_OS_TYPE" =~ (centos|rhel|almalinux|rocky) ]]; then
                echo "$WARN InterWorx on ${SYS_OS_TYPE^^} is ${YELLOW}not commonly used${NC}"
                compatible="0"
            else
                echo "$PASS InterWorx on ${SYS_OS_TYPE^^} is a ${GREEN}supported configuration${NC}"
            fi
            ;;

        none)
            echo "$PASS Standalone server (no control panel constraints)"
            ;;
    esac

    if [ "$compatible" = "0" ]; then
        echo ""
        echo "$WARN This combination may experience compatibility issues. Consider migration."
    fi

    echo ""
}

#############################################################################
# KNOWN ISSUES & RECOMMENDATIONS
#############################################################################

check_known_issues() {
    echo ""
    print_section "Known Issues & Recommendations"
    echo ""

    # CentOS 8 EOL warning
    if [ "$SYS_OS_TYPE" = "centos" ] && [ "$SYS_OS_VERSION" = "8" ]; then
        echo "$WARN CentOS 8 reached EOL on December 31, 2021"
        echo "   Recommend: Migrate to AlmaLinux 8, Rocky Linux 8, or CentOS Stream"
        echo ""
    fi

    # RHEL 7 EOL warning
    if [ "$SYS_OS_TYPE" = "rhel" ] && [ "$SYS_OS_VERSION" = "7" ]; then
        echo "$WARN RHEL 7 will reach EOL on June 30, 2024"
        echo "   Recommend: Plan upgrade to RHEL 8 or 9"
        echo ""
    fi

    # cPanel on Debian/Ubuntu
    if [ "$SYS_CONTROL_PANEL" = "cpanel" ] && [[ "$SYS_OS_TYPE" =~ (ubuntu|debian) ]]; then
        echo "$FAIL cPanel is NOT compatible with Debian/Ubuntu"
        echo "   This installation appears to be misconfigured"
        echo ""
    fi

    # Plesk version 17 and older
    if [ "$SYS_CONTROL_PANEL" = "plesk" ]; then
        local major_version=$(echo "$SYS_CONTROL_PANEL_VERSION" | cut -d. -f1)
        if [ "$major_version" -lt 18 ]; then
            echo "$WARN Plesk $major_version is out of support"
            echo "   Recommend: Upgrade to Plesk 18.0.50+ or newer"
            echo ""
        fi
    fi

    # Multiple conflicting web servers
    local web_count=0
    command_exists apache2 && ((web_count++))
    command_exists httpd && ((web_count++))
    command_exists nginx && ((web_count++))

    if [ "$web_count" -gt 1 ]; then
        echo "$WARN Multiple web servers detected on system"
        echo "   This may cause port conflicts (both trying to use port 80)"
        echo ""
    fi

    echo ""
}

#############################################################################
# MAIN EXECUTION
#############################################################################

main() {
    clear

    print_banner "OS Compatibility Check"
    echo ""
    echo "Verifying OS packages, version support, and platform compatibility..."
    echo ""

    # Show detected platform
    echo -e "${BOLD}Detected Configuration:${NC}"
    echo "  OS: ${CYAN}${SYS_OS_TYPE^^}${NC} ${SYS_OS_VERSION}"
    echo "  Kernel: $(uname -r)"
    echo "  Control Panel: ${CYAN}${SYS_CONTROL_PANEL^^}${NC}"
    echo ""

    # OS-specific package checks
    case "$SYS_OS_TYPE" in
        centos|rhel|almalinux|rocky|cloudlinux)
            check_rhel_packages
            ;;
        ubuntu|debian)
            check_debian_packages
            ;;
    esac

    # CloudLinux-specific
    check_cloudlinux_packages

    # Control panel-specific checks
    check_cpanel_packages
    check_plesk_packages
    check_interworx_packages

    # General compatibility checks
    check_os_version_support
    check_kernel_compatibility
    check_package_manager
    check_panel_os_compatibility
    check_known_issues

    # Summary
    echo ""
    print_section "Summary"
    echo ""
    echo "Compatibility check complete. Review any ${RED}failures${NC}, ${YELLOW}warnings${NC}, or ${INFO}informational${NC} items above."
    echo ""
}

# Run if sourced or executed
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
    main "$@"
fi
