#!/bin/bash
DESTDIR=""
INSTALL_DIR="/usr/bin"
CONF_DIR="/etc/pandora"
AGENT_CONF_DIR="/etc/pandora/conf"
TEMP_DIR="/var/spool/pandora/tmp/satellite_server"

PERL5PATH=/opt/pandorafms
PERL5=$PERL5PATH/perl5
PERL=$PERL5/bin/perl
REALPERL5=$PERL5


INSTALL="no"
UNINSTALL="no"
FORCE_PERL=0

function print_usage {
	echo "Usage: $0 <--install|--uninstall> [options]"
	echo "	--install	To install Pandora FMS Satellite Server on this system (you must be root)"
	echo "	--uninstall	To uninstall and remove Pandora FMS Satellite Server on this System"
	echo " "
	echo " Optional parameters:"
	echo " "
	echo "	--destdir <directory>   All files will be installed under the specified directory."
	echo " "
}

# colors
red=$'\e[0;91m'
green=$'\e[0;92m'
cyan=$'\e[0;36m'
yellow=$'\e[33m'
reset=$'\e[0m'

while [ "$1" != "" ]; do
	case "$1" in
		--install)
			INSTALL="yes"
			;;
		--uninstall)
			UNINSTALL="yes"
			;;
		--destdir)
			shift
			DESTDIR=$(echo $1 | sed -e 's/\/$//')
			;;
		--force-perl)
			FORCE_PERL=1
			;;
		*)
			print_usage
			exit 1
	esac
	shift
done

# Get distro and version
function get_distro {
	if [ -f "/etc/SuSE-release" ]
	then
		DISTRO="SUSE"
	elif [ -f "/etc/lsb-release" ] && [ ! -f "/etc/redhat-release" ]
	then
		DISTRO="UBUNTU"
	elif [ -f "/etc/debian_version" ]
	then
		DISTRO="DEBIAN"
	elif [ -f "/etc/fedora-release" ]
	then
		DISTRO="FEDORA"
	elif [ `uname -s` = "Darwin" ]
	then
		DISTRO="Darwin"
	elif [ `uname -s` = "AIX" ]
	then
		DISTRO="AIX"
	elif [ `uname -s` = "SunOS" ]
	then
		DISTRO="Solaris"
	elif [ `uname -s` = "Linux" ]
	then
		DISTRO="GENERIC"
	elif [ `uname -s` = "FreeBSD" ]
	then
		DISTRO="FreeBSD"
	elif [ `uname -s` = "NetBSD" ]
	then
		DISTRO="NetBSD"
	else
		DISTRO=`uname -s`
	fi
}

# Check that the given binary is in the PATH. Print a warning message if it is not.
function check_binary {
	BINARY="$1"

	which $BINARY >/dev/null 2>&1
	if [ $? != 0 ]
	then
		echo "ERROR: $BINARY not found. Either install it or update satellite_server.conf if it is installed."
		exit 1
	fi
}

# Function to get confirmation.
confirm() {
    local message="$1"
    local response

    echo -e "${yellow}${message}${reset}"
    read -p "Are you sure you want to proceed? (Y/y to continue): " response </dev/tty

    if [[ "$response" == "Y" || "$response" == "y" ]]; then
        return 0
    else
        echo -e "${red}Aborted${reset}"
        exit 1
    fi
}

# Guess the distro we are running on.
get_distro
echo "Pandora FMS Satellite Server installer for $DISTRO. (c) 2014-2026 Pandora FMS."
echo

if [ "$DESTDIR" != "" ]
then
	INSTALL_DIR=$DESTDIR$INSTALL_DIR
	CONF_DIR=$DESTDIR$CONF_DIR
	AGENT_CONF_DIR=$DESTDIR$AGENT_CONF_DIR
	TEMP_DIR=$DESTDIR$TEMP_DIR

	PERL5=$DESTDIR$PERL5
	PERL=$DESTDIR$PERL
fi

PERL5LIB=$PERL5/lib:$PERL5/lib/5.40.0:$PERL5/lib/5.40.0/x86_64-linux-thread-multi:$PERL5/lib/site_perl/5.40.0:$PERL5/lib/site_perl/5.40.0/x86_64-linux-thread-multi

# Install.
if [ "$INSTALL" == "yes" ]
then
    echo -e "${yellow}The Latest version of the Satellite Server includes changes that make it compatible only with ${red}Pandora FMS versions 785${reset} ${yellow}and above.${reset}"
    if [ "${PANDORA_SKIP_CONFIRMATION}" != "1" ]; then
        confirm "If your PandoraFMS Server is running a version earlier than 785, some satellite server features may not function as expected."
    fi

	check_binary "nmap"
	check_binary "fping"

	if [ -e "/usr/bin/fping" ] && [ ! -e "/usr/sbin/fping" ]
	then
		ln -s /usr/bin/fping /usr/sbin/fping
	fi

	if [ "$DESTDIR" != "" ]
	then
		echo ">Installing to directory $DESTDIR"
		mkdir -p "$DESTDIR"
		mkdir -p "$DESTDIR/var/log"
	fi

	mkdir -p "$INSTALL_DIR"
	mkdir -p "$CONF_DIR"
	mkdir -p "$AGENT_CONF_DIR"
	mkdir -p "$TEMP_DIR"

	CURRENT_RELEASE=0
	TARGET_RELEASE=0

	if [ -f "$PERL5/RELEASE" ]; then
		read -r CURRENT_RELEASE < "$PERL5/RELEASE"
	fi

    # Install perl5 according to OS
    OS_FAMILY="not_supported"

    if [ -f /etc/os-release ]; then
        . /etc/os-release  # Load variables like ID and VERSION_ID

        case "$ID" in
            rhel|centos|rocky|almalinux)
                case "$VERSION_ID" in
                    8* )
                        OS_FAMILY="el8"
                        ;;
                    9* )
                        OS_FAMILY="el9"
                        ;;
                    * )
                        OS_FAMILY="not_supported"
                        ;;
                esac
                ;;
            ubuntu)
                case "$VERSION_ID" in
                    22.04 )
                        OS_FAMILY="ubuntu2204"
                        ;;
                    * )
                        OS_FAMILY="not_supported"
                        ;;
                esac
                ;;
            * )
                OS_FAMILY="not_supported"
                ;;
        esac
    fi

    if [ "$OS_FAMILY" = "el8" ]; then
    	if [ -f "perl5.el8/RELEASE" ]; then
        	read -r TARGET_RELEASE < "perl5.el8/RELEASE"
        fi
    elif [ "$OS_FAMILY" = "el9" ]; then
    	if [ -f "perl5.el9/RELEASE" ]; then
        	read -r TARGET_RELEASE < "perl5.el9/RELEASE"
        fi
    elif [ "$OS_FAMILY" = "ubuntu2204" ]; then
    	if [ -f "perl5.ubuntu2204/RELEASE" ]; then
    		read -r TARGET_RELEASE < "perl5.ubuntu2204/RELEASE"
    	fi
    else
    	if [ -f "perl5.el9/RELEASE" ]; then
        	read -r TARGET_RELEASE < "perl5.el9/RELEASE"
        fi
    fi

    INSTALL_PERL=0
    if [ "$FORCE_PERL" -eq 1 ]; then
    	INSTALL_PERL=1
    elif [ "$TARGET_RELEASE" -ge "$CURRENT_RELEASE" ]; then
    	INSTALL_PERL=1
    fi

	if [ "$INSTALL_PERL" -eq 1 ]; then
		echo "Creating perl5 directory in $PERL5"
		rm -Rf "$PERL5"
		mkdir -p $PERL5

	    if [ "$OS_FAMILY" = "el8" ]; then
	        cp -Rp perl5.el8/* "$PERL5/"
	    elif [ "$OS_FAMILY" = "el9" ]; then
	        cp -Rp perl5.el9/* "$PERL5/"
	    elif [ "$OS_FAMILY" = "ubuntu2204" ]; then
	        cp -Rp perl5.ubuntu2204/* "$PERL5/"
	    else
	        echo "WARNING: Not supported OS found. You may need to install additional dependencies in the system."
	        cp -Rp perl5.el9/* "$PERL5/"
	    fi

	    # Create symlink to real perl5 path, used for perl compilation
	    if [ ! -e "$REALPERL5" ]; then
	    	mkdir -p "$PERL5PATH"
	    	ln -s "$PERL5" "$REALPERL5"
	    fi
	else
		echo "WARNING: A more recent perl distribution has been found, perl installation skipped."
	fi

	if [ ! -e "$PERL" ]; then
        PERL="/usr/bin/perl"
    fi

	echo
	echo ">Installing the Pandora FMS Satellite Server binary to $INSTALL_DIR..."
	cp -f satellite_server "$INSTALL_DIR" || exit 2
	chmod +x "$INSTALL_DIR/satellite_server"
	
	echo ">Installing the tentacle_client binary to $INSTALL_DIR..."
	cp -f bin/tentacle_client "$INSTALL_DIR" || exit 2
	chmod +x "$INSTALL_DIR/tentacle_client"
	
	echo ">Installing the braa binary to $INSTALL_DIR..."
	cp -f bin/braa "$INSTALL_DIR" || exit 2
	chmod +x "$INSTALL_DIR/braa"

	echo ">Installing the pandorafsnmp binary to $INSTALL_DIR..."
	cp -f bin/pandorafsnmp "$INSTALL_DIR" || exit 2
	chmod +x "$INSTALL_DIR/pandorafsnmp"
	
	echo ">Installing the wmic binary to $INSTALL_DIR..."
	cp -f bin/wmic "$INSTALL_DIR" || exit 2
	chmod +x "$INSTALL_DIR/wmic"
	
	echo ">Installing the pandorawmic binary to $INSTALL_DIR..."
	cp -f bin/pandorawmic "$INSTALL_DIR" || exit 2
	chmod +x "$INSTALL_DIR/pandorawmic"

	cp -f clean_satellite_serverd "$INSTALL_DIR" || exit 2
	chmod 0755 $INSTALL_DIR/clean_satellite_serverd

	echo ">Copying configuration file to $CONF_DIR..."
	CONF_FILE=$CONF_DIR"/satellite_server.conf"
	if [ -f $CONF_FILE ]
	then
		CONF_FILE=$CONF_DIR"/satellite_server.conf.new"
	fi
	cp -f satellite_server.conf "$CONF_FILE" || exit 3

	# Fix paths in configuration file.
	sed -i -e "s| *agent_conf_dir .*|agent_conf_dir $AGENT_CONF_DIR|" $CONF_FILE
	sed -i -e "s| *braa .*|braa $INSTALL_DIR/braa|" $CONF_FILE
	sed -i -e "s| *fsnmp .*|fsnmp $INSTALL_DIR/pandorafsnmp|" $CONF_FILE
	sed -i -e "s| *wmi_client .*|wmi_client $INSTALL_DIR/pandorawmic|" $CONF_FILE
	sed -i -e "s| *log_file .*|log_file $DESTDIR/var/log/satellite_server.log|" $CONF_FILE
	sed -i -e "s| *tentacle_client .*|tentacle_client $INSTALL_DIR/tentacle_client|" $CONF_FILE

	echo ">Copying satellite plugins"
	mkdir -p "$CONF_DIR/satellite_plugins" 2>/dev/null || exit 3
	cp -f plugins/* "$CONF_DIR/satellite_plugins/" 2>/dev/null # Allow this command to fail if there are no plug-ins for the current architecture.
	chmod +x "$CONF_DIR/satellite_plugins/"*

	if [ -d /etc/init.d ]; then
		/etc/init.d/satellite_serverd stop

		echo ">Copying startup script to /etc/init.d..."
		cp -f satellite_serverd /etc/init.d/
		if [ "$DISTRO" = "UBUNTU" ] || [ "$DISTRO" = "DEBIAN" ]
		then
			update-rc.d satellite_serverd defaults
		elif [ "$DISTRO" = "SUSE" ]
		then
			insserv satellite_serverd
		else
			INITLV=`cat /etc/inittab | grep "[0-9]\:initdefault" | cut -f 2 -d ":"`
			if [ -z "$INITLV" ]; then
				INITLV=2
			fi
			echo ">Linking startup script to /etc/rc.d/rc$INITLV.d"
			ln -s /etc/init.d/satellite_serverd /etc/rc.d/rc$INITLV.d/S90satellite_server
		fi
	fi

	if [ ! -e "$CONF_DIR/satellite_server_extra.env" ] && [ -e "$CONF_DIR/satellite_server.env" ]
    then
    	mv "$CONF_DIR/satellite_server.env" "$CONF_DIR/satellite_server_extra.env"
    else
    	touch "$CONF_DIR/satellite_server_extra.env" 2> /dev/null
	fi
	cp -f satellite_server.env $CONF_DIR/satellite_server.env

	sed -i -e "s|TMPDIR=.*|TMPDIR=\"$TEMP_DIR\"|" $CONF_DIR/satellite_server.env
	sed -i -e "s|PERL5LIB=.*|PERL5LIB=$PERL5LIB|" $CONF_DIR/satellite_server.env

	systemctl stop satellite_serverd

	PID_DIR=$DESTDIR/var/run
	[ -d "$PID_DIR" ] || mkdir -p "$PID_DIR"

	cat > /etc/systemd/system/satellite_serverd.service <<-EOF
[Unit]
Description=Pandora FMS Satellite Server

[Service]
Type=simple

User=root
PIDFile=$PID_DIR/satellite_server.pid
Restart=on-failure
ExecStartPre=$INSTALL_DIR/clean_satellite_serverd
ExecStart=$PERL -MNet::SSLeay $INSTALL_DIR/satellite_server -f $CONF_DIR/satellite_server.conf
EnvironmentFile=$CONF_DIR/satellite_server.env
EnvironmentFile=$CONF_DIR/satellite_server_extra.env

[Install]
WantedBy=multi-user.target
EOF

	systemctl daemon-reload

	if [ -d $DESTDIR/etc/logrotate.d ]
	then
		mkdir -p $DESTDIR/etc/logrotate.d
		echo "Creating logrotate.d entry for Pandora FMS log management"
		cp pandora_satellite_logrotate $DESTDIR/etc/logrotate.d/pandora_satellite
	else
		echo "Please add a log rotation schedule manually to your log rotation daemon (if any)"
	fi

	echo
	echo "Edit the file $CONF_DIR/satellite_server.conf and manually configure the Satellite Server."
	echo

	systemctl enable satellite_serverd --now
	echo "" # Avoid CI/CD test errors trying to run systemctl in docker

# Uninstall
elif [ "$UNINSTALL" == "yes" ]
then
	echo

	if [ -e "$PERL5" ]; then
		echo "WARNING: This will remove $PERL5. If you have other Pandora FMS components installed on this system that use this folder, they may stop working."
		echo -n "Are you sure you want to continue? [y/N] "
		read answer

		case "$answer" in
		    [Yy]|[Yy][Ee][Ss])
				echo ">Uninstalling the perl5 directory from $PERL5..."
				rm -Rf $PERL5
		        ;;
		    *)
		        ;;
		esac
	fi

	echo ">Uninstalling the Pandora FMS Satellite Server binary from $INSTALL_DIR..."
	rm -f "$INSTALL_DIR/satellite_server"

	echo ">Removing configuration file from $CONF_DIR..."
	rm -f "$CONF_DIR/satellite_server.conf"

	echo ">Removing agent configuration directory $AGENT_CONF_DIR..."
	rm -rf "$AGENT_CONF_DIR"

	echo ">Removing startup script from /etc/init.d..."
	rm -f /etc/init.d/satellite_serverd
	rm -f  $DESTDIR/etc/logrotate.d/pandora_satellite
	if [ "$DISTRO" = "UBUNTU" ] || [ "$DISTRO" = "DEBIAN" ]
	then
		update-rc.d -f satellite_serverd remove
	elif [ "$DISTRO" = "SUSE" ]
	then
		insserv -f satellite_serverd
	else
		INITLV=`cat /etc/inittab | grep "[0-9]\:initdefault" | cut -f 2 -d ":"`
		if [ -z "$INITLV" ]; then
			INITLV=2
		fi
		echo ">Unlinking startup script /etc/rc.d/rc$INITLV.d/S90satellite_server"
		rm -f /etc/rc.d/rc$INITLV.d/S90satellite_server
	fi

	echo "Removing service..."
	systemctl stop satellite_serverd
	rm -f /etc/systemd/system/satellite_serverd.service
	systemctl daemon-reload

else
	print_usage
fi
