#!/bin/bash
# TuxCare ePortal (https://docs.tuxcare.com/eportal/) installation script v0.01
# Copyright (c) Cloud Linux Software, Inc
#
#  Title: TuxCare ePortal Installer Script
#  Purpose: Install, configure TuxCare ePortal, and optionally configure SSL
#
#  Minimum System Requirements to support 10,000 servers:
#  Linux OS Support: AlmaLinux 8/9/10, RHEL 8/9/10, OEL 8/9/10
#                    Debian 11/12, Ubuntu 20.04/22.04/24.04
#  CPU: 1 CPU Core
#  Memory: 1G
#  Disk Space: 25G caching or 200G+ non-Caching
#
# ****************************************************************************

# Function to log messages with timestamps
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

get_server_ip() {
    # Try multiple methods to get the IP
    local ip=""

    # Method 1: ip route (most reliable for getting the IP used for internet access)
    ip=$(ip route get 8.8.8.8 2>/dev/null | grep -oP 'src \K\S+' | head -1)

    # Method 2: hostname -I (fallback)
    if [[ -z "$ip" ]]; then
        ip=$(hostname -I | awk '{print $1}')
    fi

    # Method 3: ifconfig (if available)
    if [[ -z "$ip" ]] && command -v ifconfig >/dev/null; then
        ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -1)
    fi

    echo "$ip"
}

# ============================================================================
# RED HAT VARIANT FUNCTIONS
# ==========================================Ï==================================

# Repository check function for both RHEL and Debian/Ubuntu
check_repo_content() {
    local repo_file="$1"
    local expected_content="$2"
    local repo_name="$3"
    local additional_check="$4"

    if [[ -f "$repo_file" ]]; then
        if grep -q "$expected_content" "$repo_file" && ([[ -z "$additional_check" ]] || grep -q "$additional_check" "$repo_file"); then
            log_message "$repo_name repository already exists and is properly configured."
            return 0
        else
            log_message "$repo_name repository file exists but configuration is incorrect. Updating..."
            return 1
        fi
    else
        log_message "$repo_name repository does not exist. Creating..."
        return 1
    fi
}

validate_service_rhel() {
    local service_name="$1"
    local package_name="$2"

    # Check if package is installed
    if rpm -q "$package_name" &>/dev/null; then
        log_message "$package_name is installed successfully."
    else
        log_message "ERROR: $package_name installation failed!"
        exit 1
    fi

    # Check if service exists
    if systemctl list-unit-files | grep -q "$service_name"; then
        log_message "$service_name service is available."

        # Enable the service
        systemctl enable "$service_name"

        # Check if service can start
        if systemctl start "$service_name"; then
            log_message "$service_name service started successfully."
            sleep 3

            # Verify service is running
            if systemctl is-active --quiet "$service_name"; then
                log_message "$service_name service is running."
                return 0
            else
                log_message "WARNING: $service_name service failed to start properly."
                return 1
            fi
        else
            log_message "ERROR: Failed to start $service_name service!"
            return 1
        fi
    else
        log_message "ERROR: $service_name service not found!"
        return 1
    fi
}

install_eportal_rhel() {
    clear
    log_message "Starting TuxCare ePortal installation..."
    echo

    # Check if running as root
    if [[ "$EUID" -ne 0 ]]; then
        log_message "ERROR: This script must be run as root!"
        exit 1
    fi

    log_message "Configuring Nginx repository..."

    # Check and configure Nginx repo
    if ! check_repo_content "/etc/yum.repos.d/nginx.repo" "https://nginx.org/packages/centos" "Nginx" "enabled=1"; then
        cat >/etc/yum.repos.d/nginx.repo <<EOL
[nginx]
name=nginx repo
baseurl=https://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOL
        log_message "Nginx repository configured successfully."
    fi

    sleep 2
    clear

    log_message "Configuring TuxCare ePortal repository..."

    # Check and configure TuxCare ePortal repo
    if ! check_repo_content "/etc/yum.repos.d/kcare-eportal.repo" "https://www.repo.cloudlinux.com/kcare-eportal" "TuxCare ePortal" "enabled=1"; then
        cat >/etc/yum.repos.d/kcare-eportal.repo <<EOL
[kcare-eportal]
name=KernelCare ePortal
baseurl=https://www.repo.cloudlinux.com/kcare-eportal/\$releasever/\$basearch/
enabled=1
gpgkey=https://repo.cloudlinux.com/kernelcare/RPM-GPG-KEY-KernelCare-rsa4096
gpgcheck=1
EOL
        log_message "TuxCare ePortal repository configured successfully."
    fi

    sleep 2
    clear

    # OS Detection and prerequisite installation
    log_message "Detecting operating system and installing prerequisites..."

    if [[ -f /etc/os-release ]]; then
        # shellcheck disable=SC1091
        . /etc/os-release

        case "$ID" in
        "centos")
            if [[ "$VERSION_ID" == "7" ]]; then
                log_message "Detected CentOS 7. Installing prerequisite dependencies..."
                yum install -y centos-release-scl
            else
                log_message "Detected CentOS $VERSION_ID. No specific prerequisites required."
            fi
            ;;
        "rhel")
            if [[ "$VERSION_ID" == "7" ]]; then
                log_message "Detected RHEL 7. Enabling repositories and installing dependencies..."
                subscription-manager repos --enable rhel-7-server-optional-rpms
                subscription-manager repos --enable rhel-server-rhscl-7-rpms
            else
                log_message "Detected RHEL $VERSION_ID. No specific prerequisites required."
            fi
            ;;
        "ol")
            if [[ "$VERSION_ID" == "7" ]]; then
                log_message "Detected Oracle Linux 7. Installing prerequisite dependencies..."
                yum install -y oracle-softwarecollection-release-el7
            else
                log_message "Detected Oracle Linux $VERSION_ID. No specific prerequisites required."
            fi
            ;;
        *)
            log_message "Detected $ID $VERSION_ID. No specific prerequisites required."
            ;;
        esac

    elif [[ -f /etc/redhat-release ]]; then
        if grep -q -E 'CentOS Linux release 7' /etc/redhat-release; then
            log_message "Detected CentOS 7 (via redhat-release). Installing prerequisite dependencies..."
            yum install -y centos-release-scl
        elif grep -q -E 'Red Hat Enterprise Linux Server release 7' /etc/redhat-release; then
            log_message "Detected RHEL 7 (via redhat-release). Enabling repositories..."
            subscription-manager repos --enable rhel-7-server-optional-rpms
            subscription-manager repos --enable rhel-server-rhscl-7-rpms
        elif grep -q -E 'Oracle Linux Server release 7' /etc/redhat-release; then
            log_message "Detected Oracle Linux 7 (via redhat-release). Installing prerequisites..."
            yum install -y oracle-softwarecollection-release-el7
        else
            log_message "Could not determine specific OS version from redhat-release."
        fi
    else
        log_message "WARNING: Could not determine the OS version."
    fi

    sleep 2
    clear

    # Install ePortal package
    log_message "Installing kcare-eportal package..."
    if yum -y install kcare-eportal; then
        log_message "kcare-eportal package installed successfully."
    else
        log_message "ERROR: Failed to install kcare-eportal package!"
        exit 1
    fi

    # Validate installation and service
    log_message "Validating ePortal installation and service..."
    if ! validate_service_rhel "eportal" "kcare-eportal"; then
        log_message "WARNING: ePortal service validation failed. Continuing with configuration..."
    fi
}

# ============================================================================
# DEBIAN/UBUNTU FUNCTIONS
# ============================================================================

# Function to install TuxCare GPG key
install_tuxcare_gpg_key() {
    log_message "Installing TuxCare GPG key..."
    if curl -f https://repo.cloudlinux.com/kernelcare/kernelcare.gpg -o /usr/share/keyrings/kcare-eportal.gpg; then
        log_message "GPG key downloaded successfully."

        # Verify the key file was created and has content
        if [[ -s /usr/share/keyrings/kcare-eportal.gpg ]]; then
            log_message "GPG key file verified."
        else
            log_message "ERROR: GPG key file is empty or not created properly!"
            exit 1
        fi
    else
        log_message "ERROR: Failed to download GPG key!"
        exit 1
    fi
}


validate_package_install() {
    local package_name="$1"

    if dpkg -l | grep -q "^ii.*$package_name"; then
        log_message "$package_name is installed successfully."
        return 0
    else
        log_message "ERROR: $package_name installation failed!"
        return 1
    fi
}

validate_service_debian() {
    local service_name="$1"
    local package_name="$2"

    # Check if package is installed
    if ! validate_package_install "$package_name"; then
        exit 1
    fi

    # Check if service exists
    if systemctl list-unit-files | grep -q "$service_name"; then
        log_message "$service_name service is available."

        # Enable the service
        systemctl enable "$service_name"

        # Check if service can start
        if systemctl start "$service_name"; then
            log_message "$service_name service started successfully."
            sleep 3

            # Verify service is running
            if systemctl is-active --quiet "$service_name"; then
                log_message "$service_name service is running."
                return 0
            else
                log_message "WARNING: $service_name service failed to start properly."
                return 1
            fi
        else
            log_message "ERROR: Failed to start $service_name service!"
            return 1
        fi
    else
        log_message "ERROR: $service_name service not found!"
        return 1
    fi
}

configure_firewall_debian() {
    log_message "Configuring firewall rules..."

    # Check if ufw is available and active
    if command -v ufw >/dev/null; then
        # Allow HTTP and HTTPS traffic
        if ufw allow 80/tcp && ufw allow 443/tcp && ufw allow http && ufw allow https; then
            log_message "Firewall rules configured successfully."
        else
            log_message "WARNING: Some firewall rules may not have been applied correctly."
        fi
    else
        log_message "WARNING: ufw not found. Please manually configure firewall if needed."
    fi
}

install_eportal_ubuntu() {
    local ubuntu_version="$1"
    local suite_name=""
    local repo_path=""

    case "$ubuntu_version" in
    "20.04")
        suite_name="focal"
        repo_path="20.04"
        ;;
    "22.04")
        suite_name="jammy"
        repo_path="22.04"
        ;;
    "24.04")
        suite_name="noble"
        repo_path="24.04"
        ;;
    *)
        log_message "ERROR: Unsupported Ubuntu version: $ubuntu_version"
        exit 1
        ;;
    esac

    clear
    log_message "Starting TuxCare ePortal installation for Ubuntu $ubuntu_version..."
    echo

    # Check if running as root
    if [[ "$EUID" -ne 0 ]]; then
        log_message "ERROR: This script must be run as root (use sudo)!"
        exit 1
    fi

    log_message "Configuring server for ePortal installation..."

    # Install prerequisites
    log_message "Installing prerequisites (curl, ca-certificates)..."
    if apt update && apt install -y --no-install-recommends curl ca-certificates; then
        log_message "Prerequisites installed successfully."
    else
        log_message "ERROR: Failed to install prerequisites!"
        exit 1
    fi

    # Download and install GPG key
    install_tuxcare_gpg_key

    # Configure TuxCare repository
    log_message "Configuring TuxCare ePortal repository..."

    if ! check_repo_content "/etc/apt/sources.list.d/kcare-eportal.list" "https://repo.cloudlinux.com/kcare-eportal/$repo_path" "TuxCare ePortal" "$suite_name main"; then
        cat >/etc/apt/sources.list.d/kcare-eportal.list <<EOL
deb [signed-by=/usr/share/keyrings/kcare-eportal.gpg] https://repo.cloudlinux.com/kcare-eportal/$repo_path $suite_name main
EOL
        log_message "TuxCare ePortal repository configured successfully."
    fi

    sleep 2
    clear

    # Update package lists and install ePortal
    log_message "Updating package lists and installing ePortal..."

    if apt update; then
        log_message "Package lists updated successfully."
    else
        log_message "WARNING: Package list update encountered issues. Continuing..."
    fi

    if apt install -y --no-install-recommends kcare-eportal; then
        log_message "kcare-eportal package installed successfully."
    else
        log_message "ERROR: Failed to install kcare-eportal package!"
        exit 1
    fi

    # Validate installation and service
    log_message "Validating ePortal installation and service..."
    if ! validate_service_debian "eportal" "kcare-eportal"; then
        log_message "WARNING: ePortal service validation failed. Continuing with configuration..."
    fi
}

install_eportal_debian() {
    local debian_version="$1"

    clear
    log_message "Starting TuxCare ePortal installation for Debian $debian_version..."
    echo

    # Check if running as root
    if [[ "$EUID" -ne 0 ]]; then
        log_message "ERROR: This script must be run as root (use sudo)!"
        exit 1
    fi

    log_message "Configuring server for ePortal installation..."

    # Install prerequisites
    log_message "Installing prerequisites (curl, ca-certificates)..."
    if apt update && apt install -y --no-install-recommends curl ca-certificates; then
        log_message "Prerequisites installed successfully."
    else
        log_message "ERROR: Failed to install prerequisites!"
        exit 1
    fi

    # Download and install GPG key
    install_tuxcare_gpg_key

    # Configure TuxCare repository
    log_message "Configuring TuxCare ePortal repository..."

    cat >/etc/apt/sources.list.d/kcare-eportal.list <<EOL
deb [signed-by=/usr/share/keyrings/kcare-eportal.gpg] https://repo.cloudlinux.com/kcare-eportal/debian/$debian_version kcare main
EOL
    log_message "TuxCare ePortal repository configured successfully."

    sleep 2
    clear

    # Update package lists and install ePortal
    log_message "Updating package lists and installing ePortal..."

    if apt update; then
        log_message "Package lists updated successfully."
    else
        log_message "WARNING: Package list update encountered issues. Continuing..."
    fi

    if apt install -y --no-install-recommends kcare-eportal; then
        log_message "kcare-eportal package installed successfully."
    else
        log_message "ERROR: Failed to install kcare-eportal package!"
        exit 1
    fi

    # Validate installation and service
    log_message "Validating ePortal installation and service..."
    if ! validate_service_debian "eportal" "kcare-eportal"; then
        log_message "WARNING: ePortal service validation failed. Continuing with configuration..."
    fi
}

# ============================================================================
# COMMON CONFIGURATION FUNCTIONS
# ============================================================================

configure_admin_password() {
    clear

    # Admin password configuration
    log_message "Configuring admin password..."
    echo "Your password must contain at least 10 characters."
    while true; do
        read -s -r -p "Enter your password: " varPassword
        echo
        if [[ ${#varPassword} -ge 10 ]]; then
            log_message "Password is valid. Setting admin password..."
            if kc.eportal -a admin -p "$varPassword"; then
                log_message "Admin password configured successfully."
                break
            else
                log_message "ERROR: Failed to set admin password. Please try again."
            fi
        else
            log_message "ERROR: Password must be at least 10 characters. Please try again."
        fi
    done

    sleep 2
    clear
}

configure_cache_mode() {
    # Cache Mode configuration
    log_message "Cache Mode Configuration:"
    echo ""
    echo "Would you like to enable ePortal to Cache Patches?"
    echo "This will cache meta-data and only store required patches on local server for two weeks."
    echo "This greatly reduces the size of your eportal server as well as any backups."
    echo ""
    echo "Please type 'yes' or 'no'"

    read -r varCache

    if [[ "$varCache" =~ ^[Yy][Ee][Ss]$ ]]; then
        clear
        log_message "Configuring ePortal to cache patches..."

        mkdir -p /etc/eportal
        if [[ -f "/etc/eportal/config" ]]; then
            # Check if CACHE_MODE already exists
            if ! grep -q "CACHE_MODE" /etc/eportal/config; then
                echo "CACHE_MODE = True" >>/etc/eportal/config
            fi
        else
            echo "CACHE_MODE = True" >/etc/eportal/config
        fi
        chown nginx:nginx /etc/eportal/config 2>/dev/null || chown www-data:www-data /etc/eportal/config
        log_message "Cache mode enabled successfully."
    else
        log_message "Cache mode will not be enabled."
    fi

    sleep 2
    clear
}

configure_business_units() {
    # Business Unit Separation configuration
    log_message "Business Unit Separation Configuration:"
    echo ""
    echo "Would you like to enable Managing Multiple Business Units in Isolation?"
    echo ""
    echo "Please type 'yes' or 'no'"

    read -r varBU

    if [[ "$varBU" =~ ^[Yy][Ee][Ss]$ ]]; then
        clear
        log_message "Configuring ePortal for Business Unit isolation..."

        mkdir -p /etc/eportal
        if [[ -f "/etc/eportal/config" ]]; then
            # Check if BUNITS settings already exist
            if ! grep -q "BUNITS" /etc/eportal/config; then
                cat >>/etc/eportal/config <<EOT
BUNITS = True
BUNITS_LOGIN_SELECTOR = True
BUNITS_SELECTOR = True
EOT
            fi
        else
            cat >/etc/eportal/config <<EOT
BUNITS = True
BUNITS_LOGIN_SELECTOR = True
BUNITS_SELECTOR = True
EOT
        fi
        chown nginx:nginx /etc/eportal/config 2>/dev/null || chown www-data:www-data /etc/eportal/config
        log_message "Business Unit isolation enabled successfully."
    else
        log_message "Business Unit isolation will not be configured."
    fi

    sleep 2
    clear
}

configure_proxy() {
    # Proxy configuration
    log_message "Proxy Configuration:"
    echo ""
    echo "Do you need to configure your ePortal to work with a Proxy?"
    echo "This may be required if you need FedRAMP or other security requirements."
    echo ""
    echo "**** If you configure this you will need to make sure your Proxy is properly configured. ****"
    echo "**** If you continue with this configuration now, you need to provide the Proxy URL. ****"
    echo "**** If you do not have the Proxy URL or Proxy configured, you can edit these settings later. ****"
    echo "**** Instructions: https://docs.tuxcare.com/eportal/#proxy-configuration ****"
    echo ""
    echo "Please type 'yes' or 'no'"

    read -r varAnswer

    if [[ "$varAnswer" =~ ^[Yy][Ee][Ss]$ ]]; then
        clear
        echo "Please provide your full proxy URL in format: https://example.com:3128"
        read -r varProxy

        if [[ "$varProxy" =~ ^https?:// ]]; then
            log_message "Configuring proxy settings..."

            mkdir -p /etc/eportal
            if [[ -f "/etc/eportal/config" ]]; then
                # Check if PROXY setting already exists
                if ! grep -q "PROXY" /etc/eportal/config; then
                    echo "PROXY = '$varProxy'" >>/etc/eportal/config
                fi
            else
                echo "PROXY = '$varProxy'" >/etc/eportal/config
            fi
            chown nginx:nginx /etc/eportal/config 2>/dev/null || chown www-data:www-data /etc/eportal/config
            log_message "Proxy configuration added successfully."
        else
            log_message "ERROR: Invalid proxy URL format. Skipping proxy configuration."
        fi
    else
        log_message "ePortal will not be configured for proxy."
    fi

    sleep 2
    clear
}

finalize_eportal_installation() {
    # Final service restart and validation
    log_message "Restarting ePortal service to apply all configurations..."

    systemctl stop eportal
    sleep 3

    if systemctl start eportal; then
        log_message "ePortal service restarted successfully."
        sleep 3

        # Final service validation
        if systemctl is-active --quiet eportal; then
            log_message "ePortal service is running and ready."
        else
            log_message "WARNING: ePortal service may not be running properly."
        fi
    else
        log_message "ERROR: Failed to restart ePortal service!"
        exit 1
    fi

    # Configure firewall for Debian/Ubuntu
    if [[ "$DISTRO_TYPE" == "debian" ]] || [[ "$DISTRO_TYPE" == "ubuntu" ]]; then
        configure_firewall_debian
    fi
}

display_completion_message() {
    local ssl_configured="$1"
    local domain_name="$2"

    # Get and display server IP
    SERVER_IP=$(get_server_ip)
    if [[ -n "$SERVER_IP" ]]; then
        log_message "Server IP detected: $SERVER_IP"
    else
        log_message "Could not automatically detect server IP."
        SERVER_IP="<Your-Server-IP>"
    fi

    echo
    echo "========================================="
    log_message "ePortal installation completed successfully!"
    echo "========================================="
    echo

    echo "You can now log in to your ePortal at:"
    echo "  http://$SERVER_IP"
    echo
    if [[ "$SERVER_IP" != "<Your-Server-IP>" ]] && command -v hostname >/dev/null; then
        HOSTNAME=$(hostname -f 2>/dev/null || hostname)
        if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != "localhost" ]]; then
            echo "  or http://$HOSTNAME"
            echo
        fi
    fi

    if [[ "$ssl_configured" == "yes" ]] && [[ -n "$domain_name" ]]; then
        echo "Also you may visit your ePortal at:"
        echo "  https://$domain_name"
        echo
    fi

    echo "Login credentials:"
    echo "  Username: admin"
    echo "  Password: [the password you configured]"
    echo

    # only show firewall message for Debian/Ubuntu systems
    if [[ "$DISTRO_TYPE" == "debian" ]] || [[ "$DISTRO_TYPE" == "ubuntu" ]]; then
        echo "Firewall ports opened: 80 (HTTP), 443 (HTTPS)"
        echo
    fi

    echo "For additional information on configuring feed credentials, visit:"
    echo "https://docs.tuxcare.com/eportal/#installation"
    echo
    log_message "Installation script completed."
}

# ============================================================================
# SSL CONFIGURATION FUNCTIONS
# ============================================================================

# Unified certbot installation function for all distributions
install_certbot() {
    local distro_type="$1"

    clear
    log_message "Installing certbot..."

    if [[ "$distro_type" == "rhel" ]]; then
        echo "We are going to configure the epel-release repository and"
        echo "then install and configure SNAPd"
        sleep 3
        yum -y install epel-release
        yum -y install snapd
    else
        echo "We are going to install and configure SNAPd."
        sleep 3
        apt install -y snapd
    fi

    systemctl enable --now snapd.socket
    ln -s /var/lib/snapd/snap /snap 2>/dev/null || true
    systemctl restart snapd.socket

    clear

    echo "SNAP has been installed, we need to wait a few seconds for it to seed."
    echo -n "Waiting "
    for _ in {1..10}; do
        printf "."
        sleep 3
    done

    if ! snap wait system seed.loaded; then
        echo "Snap seed did not load successfully"
        exit 1
    fi
    echo
    snap install core
    snap refresh core

    clear
    echo "We are now going to install CertBot for Let's Encrypt"
    snap install --classic certbot
    ln -s /snap/bin/certbot /usr/bin/certbot 2>/dev/null || true
    echo "CertBot is installed"
    sleep 3
    clear
}

configure_ssl_certificate() {
    local distro_type="$1"

    echo "We are about to install your SSL certificate, but first we need some information."
    echo "Please type your domain name in all lowercase."
    read -r varDomain_name

    echo "Domain Name: $varDomain_name"
    echo
    echo "Please type in your email address:"
    read -r varEmail
    echo "Email address: $varEmail"
    sleep 3

    echo "During the installation you will be asked if you want to opt in to Let's Encrypt Feedback list."
    echo "We will let you select how you would like to respond to this yourself."
    sleep 5

    echo "Installing the SSL certificate..."
    certbot certonly --nginx -m "$varEmail" --agree-tos -d "$varDomain_name" --key-type ecdsa --elliptic-curve secp384r1

    echo "Configuring nginx..."
    mv /etc/nginx/eportal.ssl.conf.example /etc/nginx/eportal.ssl.conf
    grep -c "include eportal.ssl.conf;" /etc/nginx/conf.d/eportal.conf || sed -i "3i \ include eportal.ssl.conf;" /etc/nginx/conf.d/eportal.conf
    sed -i -e "s|server_name.*|server_name $varDomain_name;|g" /etc/nginx/eportal.ssl.conf
    sed -i -e "s|ssl_certificate .*|ssl_certificate /etc/letsencrypt/live/$varDomain_name/fullchain.pem;|" /etc/nginx/eportal.ssl.conf
    sed -i -e "s|ssl_certificate_key .*|ssl_certificate_key /etc/letsencrypt/live/$varDomain_name/privkey.pem;|" /etc/nginx/eportal.ssl.conf

    # disable ssl_stapling and ssl_stapling_verify because let's encrypt stopped providing OCSP
    # https://letsencrypt.org/2025/08/06/ocsp-service-has-reached-end-of-life
    sed -i -e 's|ssl_stapling|# &|' /etc/nginx/eportal.ssl.conf

    echo "The certificate has been installed. We are now going to restart Nginx."
    # Restart Nginx
    systemctl restart nginx

    # Check status
    if systemctl is-active --quiet nginx; then
        echo "Nginx restarted successfully"
    else
        echo "Failed to restart Nginx"
    fi

    sleep 3
    clear

    # Enable port 443 in firewall
    if [[ "$distro_type" == "rhel" ]]; then
        echo "Checking firewall for port 443..."

        # Check if firewalld is running and enabled
        if systemctl is-active firewalld &>/dev/null && systemctl is-enabled firewalld &>/dev/null; then
            # Check if port 443 is already enabled
            if firewall-cmd --query-port=443/tcp 2>/dev/null | grep -q 'yes'; then
                echo "Port 443 is already enabled"
            else
                # Enable port 443
                echo "Enabling port 443..."
                firewall-cmd --add-port=443/tcp --permanent
                firewall-cmd --reload
            fi
        else
            echo "Firewalld is not running and enabled"
        fi
    else
        echo "Checking UFW firewall for port 443..."

        # Check if ufw is available and active
        if command -v ufw >/dev/null; then
            if ufw status | grep -q "Status: active"; then
                # Check if port 443 is enabled
                if ufw status | grep -q "443/tcp.*ALLOW"; then
                    echo "Port 443 is already enabled"
                else
                    echo "Enabling port 443"
                    ufw allow 443/tcp
                fi
            else
                echo "UFW is not enabled"
            fi
        fi
    fi

    echo
    echo "Done!"
    echo

}

# ============================================================================
# MAIN SCRIPT
# ============================================================================

clear
echo "****************************************************************************"
echo " Title: TuxCare ePortal Unified Installer Script"
echo " Purpose: Install and configure TuxCare ePortal with optional SSL"
echo
echo "    Minimum System Requirements to support 10,000 servers"
echo " Linux OS Support: AlmaLinux 8/9/10, RHEL 8/9/10, OEL 8/9/10"
echo "                   Debian 11/12, Ubuntu 20.04/22.04/24.04"
echo " CPU: 1 CPU Core"
echo " Memory: 1G"
echo " Disk Space: 25G caching or 200G+ non-Caching"
echo

# Prompt the user to agree to the terms
read -r -p "Do you agree to these terms? (y/n): " response

# Check if the user agreed to the terms
if [[ "$response" != "y" ]]; then
    echo "You did not agree to the terms. Exiting script."
    exit 1
fi

# Proceed with the script
echo "You agreed to the terms. Continuing with the script."

# Detect the Linux distribution
DISTRIBUTION=$(lsb_release -is 2>/dev/null)

# If lsb_release is unavailable, try another method
if [[ -z "$DISTRIBUTION" ]]; then
    if [[ -f /etc/redhat-release ]]; then
        DISTRIBUTION="RedHat"
    elif [[ -f /etc/debian_version ]]; then
        if [[ -f /etc/os-release ]]; then
            # shellcheck disable=SC1091
            . /etc/os-release
            DISTRIBUTION="$ID"
        else
            DISTRIBUTION="Debian"
        fi
    else
        DISTRIBUTION="Unknown"
    fi
fi

# Convert to lowercase for comparison
DISTRIBUTION_LOWER=$(echo "$DISTRIBUTION" | tr '[:upper:]' '[:lower:]')

# Detect version information
if [[ "$DISTRIBUTION_LOWER" == "ubuntu" ]]; then
    UBUNTU_VERSION=$(lsb_release -rs 2>/dev/null)
    if [[ -z "$UBUNTU_VERSION" ]] && [[ -f /etc/os-release ]]; then
        # shellcheck disable=SC1091
        . /etc/os-release
        UBUNTU_VERSION="$VERSION_ID"
    fi
    DISTRO_TYPE="ubuntu"
elif [[ "$DISTRIBUTION_LOWER" == "debian" ]]; then
    DEBIAN_VERSION=$(cat /etc/debian_version 2>/dev/null | cut -d'.' -f1)
    if [[ -z "$DEBIAN_VERSION" ]] && [[ -f /etc/os-release ]]; then
        # shellcheck disable=SC1091
        . /etc/os-release
        DEBIAN_VERSION="$VERSION_ID"
    fi
    DISTRO_TYPE="debian"
elif [[ "$DISTRIBUTION_LOWER" == "redhat" ]] || [[ -f /etc/redhat-release ]]; then
    DISTRO_TYPE="rhel"
else
    DISTRO_TYPE="unknown"
fi

# Execute installation based on the Linux distribution
if [[ "$DISTRO_TYPE" == "rhel" ]]; then
    # Execute ePortal installation for Red Hat variants
    install_eportal_rhel

elif [[ "$DISTRO_TYPE" == "ubuntu" ]]; then
    # Execute ePortal installation for Ubuntu
    if [[ -n "$UBUNTU_VERSION" ]]; then
        if [[ "$UBUNTU_VERSION" =~ ^20\.04 ]]; then
            install_eportal_ubuntu "20.04"
        elif [[ "$UBUNTU_VERSION" =~ ^22\.04 ]]; then
            install_eportal_ubuntu "22.04"
        elif [[ "$UBUNTU_VERSION" =~ ^24\.04 ]]; then
            install_eportal_ubuntu "24.04"
        else
            echo "Unsupported Ubuntu version detected: $UBUNTU_VERSION"
            exit 1
        fi
    else
        echo "Could not detect Ubuntu version"
        exit 1
    fi

elif [[ "$DISTRO_TYPE" == "debian" ]]; then
    # Execute ePortal installation for Debian
    if [[ "$DEBIAN_VERSION" == "11" ]]; then
        install_eportal_debian "11"
    elif [[ "$DEBIAN_VERSION" == "12" ]]; then
        install_eportal_debian "12"
    else
        echo "Unsupported Debian version detected: $DEBIAN_VERSION"
        exit 1
    fi

else
    echo "Unsupported distribution detected: $DISTRIBUTION"
    exit 1
fi

# Configure common settings
configure_admin_password
configure_cache_mode
configure_business_units
configure_proxy

# Finalize ePortal installation
finalize_eportal_installation

# Ask if user wants to configure SSL
clear
echo
echo "========================================="
echo " SSL Certificate Configuration"
echo "========================================="
echo
echo "Would you like to configure an SSL certificate using Let's Encrypt?"
echo "This requires:"
echo "  - A valid FQDN (Fully Qualified Domain Name)"
echo "  - DNS properly configured and pointing to this server"
echo
echo "Please type 'yes' or 'no'"
read -r ssl_answer

SSL_CONFIGURED="no"
DOMAIN_NAME=""

if [[ "$ssl_answer" =~ ^[Yy][Ee][Ss]$ ]]; then
    clear
    log_message "Starting SSL certificate configuration..."

    # Install certbot
    install_certbot "$DISTRO_TYPE"

    # Configure SSL certificate
    configure_ssl_certificate "$DISTRO_TYPE"
    DOMAIN_NAME=$varDomain_name
    SSL_CONFIGURED="yes"
else
    log_message "SSL certificate will not be configured."
    echo "You can configure SSL later by running the certbot commands manually."
    sleep 3
fi

# Display completion message
clear
display_completion_message "$SSL_CONFIGURED" "$DOMAIN_NAME"
