#!/usr/bin/bash
#
#  Copyright (C) 2002-25 - ntop.org
#
#  http://www.ntop.org/
#
##############################

set -e
set -o pipefail

cmd=()

TMP_FILE="/tmp/ntop-installer.tmp"

# Exit function
function checkExit {
    {
	if (whiptail --title "Exit" --yesno "Do you want to exit?" 8 78); then
	    /bin/rm $TMP_FILE
    	    exit
	else
    	    mainMenu
	fi
    }
}

##############################

function install_clickhouse() {
    if test -f "/usr/bin/lsb_release"; then
	if ! test -f "/usr/share/keyrings/clickhouse-keyring.gpg"; then
	    # Install prerequisite packages
	    apt-get install -y apt-transport-https ca-certificates curl gnupg

	    # Download the ClickHouse GPG key and store it in the keyring
	    curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg

	    # Get the system architecture
	    ARCH=$(dpkg --print-architecture)

	    # Add the ClickHouse repository to apt sources
	    echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg arch=${ARCH}] https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list

	    # Update apt package lists
	    apt update
	    apt -y install clickhouse-client clickhouse-server
	fi
    else
	yum install -y yum-utils
	yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo
	yum install -y clickhouse-client clickhouse-server
    fi
}

##############################

function install() {
    EXIT_CODE=0

    if test -f "/usr/bin/lsb_release"; then
	apt -y install $1 || EXIT_CODE=?
    else
	dnf install -y $1 || EXIT_CODE=?
    fi

    if [ "$EXIT_CODE" = "0" ]; then
	whiptail --title "Report" --msgbox "$1 installed successfully. $2" 12 80
    else
	whiptail --title "Error" --msgbox "Error while installing $1" 12 80
    fi
}

##############################

function remove() {
    EXIT_CODE=0

    if test -f "/usr/bin/lsb_release"; then
	apt -y remove $1 || EXIT_CODE=?
    else
	dnf remove -y $1 || EXIT_CODE=?
    fi

    if [ "$EXIT_CODE" = "0" ]; then
	whiptail --title "Report" --msgbox "$1 removed successfully" 12 80
    else
	whiptail --title "Error" --msgbox "Error while removing $1" 12 80
    fi
}

##############################

function is_installed() {
    NUM=`cut -f 1  $TMP_FILE | grep -E "$1$" | wc -l`
    
    if test "$NUM" -lt 1; then
	echo "OFF"
    else
	echo "ON"
    fi
}

##############################

function is_ntopng_installed() {
    is_installed "ntopng"
}

##############################

function is_nedge_installed() {
    is_installed "nedge"
}

##############################

function is_clickhouse_installed() {
    is_installed "clickhouse-server"
}

##############################

function is_nprobe_installed() {
    is_installed "nprobe"
}
##############################

function is_cento_installed() {
    is_installed "cento"
}

##############################

function is_pfring_installed() {
    is_installed "pfring"
}

##############################

function is_n2disk_installed() {
    is_installed "n2disk"
}

##############################

function is_ntap_installed() {
    is_installed "ntap"
}

##############################

function is_nscrub_installed() {
    is_installed "nscrub"
}

##############################

function is_ipt_geofence_installed() {
    is_installed "ipt_geofence"
}

##############################

function refresh_package_list() {
    MODE=$2
    
    if ! test -f "/usr/bin/lsb_release"; then
	dnf list --installed | cut -d '.' -f 1 > $TMP_FILE
    else
	dpkg --get-selections | grep -v deinstall | cut -d ' ' -f 1 > $TMP_FILE
    fi

    NTOPNG=$(is_ntopng_installed)
    NEDGE=$(is_nedge_installed)
    CLICKHOUSE=$(is_clickhouse_installed)
    NPROBE=$(is_nprobe_installed)
    CENTO=$(is_cento_installed)
    PFRING=$(is_pfring_installed)
    N2DISK=$(is_n2disk_installed)
    NTAP=$(is_ntap_installed)
    NSCRUB=$(is_nscrub_installed)
    GEOFENCE=$(is_ipt_geofence_installed)

    cmd=()

    if test $NTOPNG == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("ntopng")
	else
	    cmd+=("ntopng" "ntopng" $NTOPNG)
	fi
    fi

    if test "$CLICKHOUSE" == "$1"; then
	if ! test $MODE == "update"; then
	    # We do not update clickhouse as it will require pwd to be entered
	    cmd+=("clickhouse" "Clickhouse DB" $CLICKHOUSE)
	fi
    fi

    if test $NPROBE == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("nprobe")
	else
	    cmd+=("nprobe" "nProbe" $NPROBE)
	fi
    fi

    if test $CENTO == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("cento")
	else
	    cmd+=("cento"  "nProbe Cento" $CENTO)
	fi
    fi

    if test $PFRING  == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("pfring")
	else
	    cmd+=("pfring"     "PF_RING" $PFRING)
	fi
    fi

    if test $N2DISK  == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("n2disk")
	else
	    cmd+=("n2disk" "Network-to-Disk" $N2DISK)
	fi
    fi

    if test $NTAP == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("ntap")
	else
	    cmd+=("ntap"   "Network Tap" $NTAP)
	fi
    fi

    if test $NSCRUB == "$1"; then
	if test $MODE == "update"; then
	    cmd+=("nscrub")
	else
	    cmd+=("nscrub" "nScrub DDoS Protection" $NSCRUB)
	fi
    fi

    if test -f "/usr/bin/lsb_release"; then
	if test $NEDGE == "$1"; then
	    if test $MODE == "update"; then
		cmd+=("nedge")
	    else	    		
		UBUNTU_RELEASE=`/usr/bin/lsb_release -r  | cut -f 2`

		if [ "$UBUNTU_RELEASE" == "20.04" ] || [ "$UBUNTU_RELEASE" == "24.04" ]; then
		    cmd+=("nedge"        "ntopng Edge (nEdge)" $NEDGE)
		fi

		if test $GEOFENCE == "$1"; then
		    cmd+=("ipt_geofence" "GeoFencing Host Protection" $GEOFENCE)
		fi
	    fi
	fi
    fi

    CMD="${cmd[@]}"
}

##############################

function installMenu {
    refresh_package_list "OFF" "install"

    OPTIONS=$(whiptail --title "Install Packages" --nocancel --checklist \
		       "Select the ntop packages you would like to install: those already installed are hidden." 20 78 12 \
		       "${cmd[@]}" 3>&1 1>&2 2>&3)

    EXIT_STATUS=$?

    if [ $EXIT_STATUS = 0 ]; then
	if test $NTOPNG == "OFF"; then
	    if [[ $OPTIONS == *"ntopng"* ]]; then
		install "ntopng ntopng-data"
	    fi
	fi

	if [[ $OPTIONS == *"nedge"* ]]; then
	    if test $NEDGE == "OFF"; then
		install "nedge ntopng-data"
	    fi
	fi

	if [[ $OPTIONS == *"clickhouse"* ]]; then
	    if test $CLICKHOUSE == "OFF"; then
		install_clickhouse
	    fi
	fi

	if [[ $OPTIONS == *"nprobe"* ]]; then
	    if test $NPROBE == "OFF"; then
		install "nprobe"
	    fi
	fi

	if [[ $OPTIONS == *"cento"* ]]; then
	    if test $CENTO == "OFF"; then
		install "cento"
	    fi
	fi

	if [[ $OPTIONS == *"pfring"* ]]; then
	    if test $PFRING == "OFF"; then
	    install "pfring pfring-dkms" "Please run 'sudo pf_ringcfg' to configure PFRING drivers and interfaces"
	    fi
	fi

	if [[ $OPTIONS == *"n2disk"* ]]; then
	    if test $N2DISK == "OFF"; then
		install "n2disk"
	    fi
	fi

	if [[ $OPTIONS == *"ntap"* ]]; then
	    if test $NTAP == "OFF"; then
		install "ntap"
	    fi
	fi

	if [[ $OPTIONS == *"nscrub"* ]]; then
	    if test $NSCRUB == "OFF"; then
		install "nscrub"
	    fi
	fi

	if [[ $OPTIONS == *"ipt_geofence"* ]]; then
	    if test $GEOFENCE == "OFF"; then
		install "ipt_geofence"
	    fi
	fi
    fi

    mainMenu
}

##############################

function removeMenu {
    refresh_package_list "ON" "remove"

    OPTIONS=$(whiptail --title "Remove Packages" --nocancel --checklist \
		       "Deselect the installed ntop packages you would like to remove: those not installed are hidden" 20 78 12 \
		       "${cmd[@]}" \
		       3>&1 1>&2 2>&3)

    EXIT_STATUS=$?

    if [ $EXIT_STATUS = 0 ]; then
	if test $NTOPNG == "ON"; then
	    if ! [[ $OPTIONS == *"ntopng"* ]]; then
		remove "ntopng ntopng-data"
	    fi
	fi

	if test $NEDGE == "ON"; then
	    if ! [[ $OPTIONS == *"nedge"* ]]; then
		 if ! test -f "/usr/bin/lsb_release"; then
		     whiptail --title "Error" --msgbox "This application is not available on this platform" 12 80
		 else
		     remove "nedge ntopng-data"
		 fi
	    fi
	fi

	if test $NPROBE == "ON"; then
	    if ! [[ $OPTIONS == *"nprobe"* ]]; then
		remove "nprobe"
	    fi
	fi

	if test $CENTO == "ON"; then
	    if ! [[ $OPTIONS == *"cento"* ]]; then
		remove "cento"
	    fi
	fi

	if test $PFRING == "ON"; then
	    if ! [[ $OPTIONS == *"pfring"* ]]; then
		remove "pfring pfring-dkms"
	    fi
	fi

	if test $N2DISK == "ON"; then
	    if ! [[ $OPTIONS == *"n2disk"* ]]; then
		remove "n2disk"
	    fi
	fi

	if test $NTAP == "ON"; then
	    if ! [[ $OPTIONS == *"ntap"* ]]; then
		remove "ntap"
	    fi
	fi

	if test $NSCRUB == "ON"; then
	    if ! [[ $OPTIONS == *"nscrub"* ]]; then
		remove "nscrub"
	    fi
	fi

	if test $GEOFENCE == "ON"; then
	    if ![[ $OPTIONS == *"ipt_geofence"* ]]; then
		remove "ipt_geofence"
	    fi
	fi
    fi

    mainMenu
}

##############################

function updateMenu {
    refresh_package_list "ON" "update"

    PKGS=${cmd[@]}

    if test -z "$PKGS"; then
	whiptail --title "Update Report" --msgbox "Nothing to update" 12 80
    else	
	# Updating...
	{
	    for ((i = 0 ; i <= 100 ; i+=25)); do
		if test $i = 0; then
		    if ! test -f "/usr/bin/lsb_release"; then
			dnf install -y $PKGS
		    else
			apt -y install $PKGS 3>&2 2>&1 1>&3 > /dev/null || true
		    fi
		else
		    sleep 0.1
		fi
		
		echo $i
	    done
	} | whiptail --gauge "Updating $PKGS" 6 50 0

	whiptail --title "Update Report" --msgbox "$PKGS updated succesfully" 12 80
    fi

    mainMenu
}

##############################

# Main menu function
function mainMenu {
	# Main Menu
	CHOICE=$(
	    whiptail --title "Select the operation you want to do" --menu "Choose an option:" 25 78 16 \
         	     "<-- Exit" "" \
         	     "Install" "Install ntop packages." \
         	     "Remove"  "Remove installed ntop packages." \
		     "Update"  "Update installed ntop packages." \
		     3>&2 2>&1 1>&3
	      )

	# Choosing the choice
	case $CHOICE in
            "<-- Exit")
                checkExit
        	;;
            "Install")
                installMenu
        	;;
            "Remove")
                removeMenu
        	;;
            "Update")
                updateMenu
        	;;
	esac
}

# Changing the colors of whiptail
export NEWT_COLORS='
root=black,blue
listbox=black,lightgray
actlistbox=black,lightgray
checkbox=black,lightgray
'

if [ "$EUID" -ne 0 ]
then
    echo "This tool requires root privileges. Try again with \"sudo \" please ..."
    exit
fi

# Starting up...
{
    for ((i = 0 ; i <= 100 ; i+=25)); do
	if test $i = 0; then
	    if ! test -f "/usr/bin/lsb_release"; then
		dnf install -y epel-release
		dnf update -y
	    else
		apt update 3>&2 2>&1 1>&3 > /dev/null || true
	    fi
	else
	    sleep 0.1
	fi

        echo $i
    done
} | whiptail --gauge "Starting up..." 6 50 0


# Starting the main loop
mainMenu

/bin/rm $TMP_FILE
