#!/bin/bash -e

cd $(dirname $(readlink -e "$0"))
. ./libinstall.sh

# Explicitly set umask
umask 0022

do_install_check

proddir="/var/www/html/nagioslogserver"
backenddir="/usr/local/nagioslogserver"
DEVEL="False"
NTP_SERVER="pool.ntp.org"

usage() {
	cat <<-EOF

		Nagios Log Server Installer
		Copyright 2014-2018, Nagios Enterprises LLC.
		License:
			Nagios Software License <http://assets.nagios.com/licenses/nagios_software_license.txt>

		Usage: ./fullinstall [options...]

		Options:
			-h | --help
				Display this help text
			-a | --add_node
				
			-m | --manager
				
			-i | --id

			-k | --token

			--node-name
            
            -t | --ntp-server
                Custom NTP server for initial time sync (Default pool.ntp.org)
				
			-n | --non-interactive
				Assume defaults for all questions (for scripted installs)

	EOF
}


#####################
### INSTALL STEPS ###
#####################

prereqs() {
	local pkgs

	# Install prereqs
	if [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
        if [ "$distro" == "Ubuntu" ] && [ -f /etc/apt/sources.list.d/debian.list ]; then
            rm /etc/apt/sources.list.d/debian.list
        fi

		export DEBIAN_FRONTEND=noninteractive
		export PERL_MM_USE_DEFAULT=1

		extra="php libapache2-mod-php php-cli php-curl php-ldap php-dev vim"
		python_pkgs="python3 python-is-python3 python3-pip python3-openssl"

		extra="$extra snmp-mibs-downloader"

		if [ "$distro" == "Debian" ]; then
			# Check if non-free is in sources.list and add it if missing
			if ! grep -q '^deb.*\bnon-freei\b' /etc/apt/sources.list; then
				# Backup original sources.list
				cp /etc/apt/sources.list /etc/apt/sources.list.bak
				# Add non-free to each deb line that doesn't already have it
				sed -i '/^deb.*main/ s/$/ non-free /' /etc/apt/sources.list
			fi
		fi

		if [ "$dist" == "ubuntu24" ]|| [ "$dist" == "debian12" ]; then
			if [ "$dist" == "ubuntu24" ]; then
				extra="$extra python3.12-venv tzdata-legacy"
			fi
			dpkg --purge systemd-timesyncd
		fi

        if [ "$dist" == "debian11" ] || [ "$dist" == "debian12" ]; then
            python_pkgs="$python_pkgs python3-venv"
        elif [ "$dist" == "ubuntu22" ]; then
            python_pkgs="$python_pkgs python3.10-venv"
        elif [ "$dist" == "ubuntu24" ]; then
            python_pkgs="$python_pkgs python3.12-venv"
		fi

		pkgs="byacc curl cron rsyslog locales libcairo2-dev gcc libglib2.0-dev libc6 libxml2-dev make snmp ntp openssl patch libpango1.0-dev sendmail-bin apache2 fonts-ipafont-mincho fonts-ipafont-gothic sudo sysstat unzip xfonts-75dpi xfonts-base zip net-tools $python_pkgs $extra"

		apt-get -y update
		apt-get -y install $pkgs

		# Install perl modules from CPAN instead of random packages from distros
		cpan install CPAN ||:
		cpan install ExtUtils::MakeMaker ||:

		# Set up languages for the install
        (
            cd nagioslogserver/basedir/html/application/language
            for lang in *; do
                if [ -d "$lang" ]; then
                    if [ "$dist" == "debian11" ] || [ "$dist" == "debian12" ]; then
                        sed -i "/#[[:blank:]]*$lang/s/#//" /etc/locale.gen
                    else
                        locale-gen "$lang" &> /dev/null
                        locale-gen "$lang.UTF-8" &> /dev/null
                    fi
                fi
            done
            echo "Configuring locale... this might take a minute..."
            if [ `command -v locale-update` ]; then
                locale-update &> /dev/null
            else
                locale-gen &> /dev/null
            fi
        )
	else
		# Add the epel repo before continuing
		add_yum_repo "epel"
		pip="python-pip"
		if [ "$dist" == "el7" ]; then
			pip="python2-pip"
		elif [ "$dist" == "el8" ]; then
			pip="python3-pip"
		else
			pipextra="urllib3==1.22"
		fi

		cjk_fonts="ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts"
		if [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
			cjk_fonts="google-noto-sans-cjk-ttc-fonts google-noto-serif-cjk-ttc-fonts" 
		fi

		python_pkgs="pyOpenSSL python"
		if [ "$dist" == "el8" ]; then
			python_pkgs="python3 python3-pyOpenSSL"
		fi

		ntp_pkg="ntp"
		if [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
			ntp_pkg="chrony"
		fi

		el8_extras=""
		if [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
			el8_extras="php-json php-xml php-soap postfix cyrus-sasl-plain  glibc-langpack-bg glibc-langpack-cs glibc-langpack-de glibc-langpack-es glibc-langpack-fr glibc-langpack-it glibc-langpack-ja glibc-langpack-ko glibc-langpack-pl glibc-langpack-pt glibc-langpack-ru glibc-langpack-zh"
		fi

		el9_extras=""
		if [ "$dist" == "el9" ]; then
			el9_extras="initscripts compat-openssl11"
		fi

		php_devel=""
		if [ "$dist" != "el7" ] || [ "$distro" != "RedHatEnterpriseServer" ]; then
			# This package is only unavailable on rhel 7
			php_devel="php-devel"
		fi
		pkgs="$pip $cjk_fonts $python_pkgs $ntp_pkg $el8_extras $el9_extras $php_devel rsyslog byacc cairo-devel gcc glib2-devel glibc java-1.8.0-openjdk libxml2-devel make net-snmp net-snmp-utils openssl patch pango-devel perl-ExtUtils-MakeMaker sendmail httpd php php-cli rc wget sudo sysstat unzip zip net-tools php-ldap php-fpm"

		yum -y install $pkgs
	fi
	
	set +e

	# Set date/time because ssl certificates can be in the future... (fix for pypi and get-pip)
	if [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
		ntpq -p
	elif [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
		chronyd -q "server $NTP_SERVER iburst"
	else
		ntpdate -u $NTP_SERVER
	fi

	set -e
    
    # install argparse and jsonselect
    pipbin="pip"
	pythonbin="python"
    if [ "$dist" == "el8" ]; then
        pipbin="pip3"
		pythonbin="python3"
    fi
	
	(
		# click 8.0.0 is incompatible with Python 2.x
		$pythonbin -m venv /usr/local/nagioslogserver/pythonvenv
		source /usr/local/nagioslogserver/pythonvenv/bin/activate
		$pipbin install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --upgrade click==7.1.2 argparse $pipextra
	)

	# Make sure they were installed (on RHEL/CentOS since it's easy to check)
	if [ "$distro" != "Ubuntu" ] && [ "$distro" != "Debian" ]; then
		if ! is_installed $pkgs; then
			error "Prerequisites failed to install."
		fi
	fi
}


sourceguardian() {
	#~ install_sourceguardian
	echo "Installing sourceguardian..."
    install_sourceguardian
}


timezone() {
	php_timezone
}


nagioslogserver() {

	# Copy source directory to the system
	mkdir -p "$proddir"
	cp -r nagioslogserver/basedir/html/* "$proddir"

	# Set up permissions
	for dir in application/cache application/config www/media www/scripts application/dashboards; do
		chgrp -R "$apacheuser" "$proddir/$dir"
		chmod -R ug+rwx "$proddir/$dir"
	done

	# Install site-specific config file
	#cp config.local.php "$proddir/application/config/"

	if [ $DEVEL == "True" ]; then
		echo -e "\n\n" >> $proddir/application/config/config.local.php
        echo '$config["dev_mode"] = TRUE;' >> $proddir/application/config/config.local.php
	fi

	if [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
		echo "clear_env = no" >> /etc/php-fpm.d/www.conf
		sed -i 's/^.*catch_workers_output.*/catch_workers_output = yes/' /etc/php-fpm.d/www.conf
		sed -i 's_php-fpm/error.log_php-fpm/www-error.log_' /etc/php-fpm.conf

	fi

	# Generate a random key value for encryption_key
 	key=$(openssl rand -hex 32)
  	sed -i "/\$config\['encryption_key'\]/c\$config['encryption_key'] = '$key';" $proddir/application/config/config.local.php

	# Do some special changes if we are on Ubuntu/Debian
    if [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
        # Activate module mod_rewrite
        a2enmod rewrite

        # Remove the default configuration
        a2dissite 000-default.conf

        # Copy over our version (add Document Root)
        echo "DocumentRoot /var/www/html" > "$httpdconfdir/nagioslogserver.conf"
        cat nagioslogserver/httpd.nagioslogserver.2.conf >> "$httpdconfdir/nagioslogserver.conf"

        # Enable the new nagios config
        a2ensite nagioslogserver.conf

    else
        # Install Apache config
        if [ "$dist" == "el7" ] || [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
            cp nagioslogserver/httpd.nagioslogserver.2.conf "$httpdconfdir/nagioslogserver.conf"
        else
            cp nagioslogserver/httpd.nagioslogserver.conf "$httpdconfdir/nagioslogserver.conf"
        fi
    fi
	
	#Enable and restart sendmail on el 8/9
	if [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
		systemctl enable sendmail
		systemctl restart sendmail
	fi
	
	# Restart apache
	if [ `command -v systemctl` ]; then
		systemctl restart $httpd
	else
		service $httpd restart
	fi
}


backend() {
	# Setup the backend items
	add_user nagios
	add_group nagios
	add_to_groups nagios nagios "$apachegroup"
	add_to_groups "$apacheuser" nagios
	set_primary_group nagios nagios
	
	mkdir -p "$backenddir/var" "$backenddir/etc" "$backenddir/tmp" "$backenddir/scripts" "$backenddir/snapshots" "$backenddir/mibs"
	cp -r nagioslogserver/basedir/scripts/* "$backenddir/scripts"
	cp -r nagioslogserver/basedir/etc/* "$backenddir/etc"
	cp -r nagioslogserver/basedir/var/* "$backenddir/var"
	touch "$backenddir/var/auditlog.log"
	cp -r mibs/* "$backenddir/mibs"

	touch "$backenddir/var/chromium_report.log"
	chown $nagiosuser:$nagiosgroup "$backenddir/var/chromium_report.log"
	chmod 0664 "$backenddir/var/chromium_report.log"
	
	chown -R nagios:nagios "$backenddir"
	chown -R nagios:"$apachegroup" "$backenddir/tmp"
	chown -R "$apacheuser:$apachegroup" "$proddir/www"
	chown -R "$apacheuser:$apachegroup" "$proddir/application"
	chmod -R og-w "$backenddir"
	chmod -R 0664 "$backenddir/var"
	chmod 775 "$backenddir/var"
	chmod 775 "$backenddir/tmp"
	chmod 0554 $backenddir/scripts/*
	chmod 0554 $backenddir/scripts
	for script in change_timezone.sh reconfigure_ncpa.sh get_logstash_ports.sh profile.sh reconfigure_ncpa.sh; do
		chown root:root $backenddir/scripts/$script
	done
	
	# Install opensearch
	(
		cd subcomponents/opensearch

	    # Generate a random password for the OpenSearch User
		nlspass="$(tr -dc '[:alnum:]' < /dev/urandom | head -c 20)"

		./install "$distro" "$dist" "$apacheuser" "$apachegroup" "$nagiosuser" "$nagiosgroup" "$nlspass" "$proddir" "$ADDING_NODE" "$MANAGER_BASE_URL" "$NODE_NAME" "$API_TOKEN"
	)
	
	# Install logstash
	(
		cd subcomponents/logstash
		./install "$distro" "$dist" "$apacheuser" "$apachegroup" "$nagiosuser" "$nagiosgroup"

		if [ "$ADDING_NODE" == "true" ]; then
			curl "$MANAGER_BASE_URL/api/system/apply_config_to_node?node=$NODE_NAME&token=$API_TOKEN"
		fi
	)
	
	# Install NCPA
	(
		cd subcomponents/ncpa
		./install "$distro" "$dist" "$ver"
	)

	# Install Chromium
	(
		cd subcomponents/chromium
		./install "$distro" "$dist"
	)

	update_java_logging_configs

	"$backenddir/scripts/generate_uuid.sh" -f "$backenddir/var/node_uuid"
    
    #install cron
    sed -i "s/@APACHE@/$apacheuser/g" nagioslogserver/nagioslogserver.cron.d
    install -m 644 nagioslogserver/nagioslogserver.cron.d /etc/cron.d/nagioslogserver 
	
	# Add backup storage area
	mkdir -p /store/backups/nagioslogserver
	chown nagios:nagios -R /store

	# Set php.ini defaults
	echo "Checking php.ini defaults..."
	for file in $(find /etc -name "php.ini"); do
		# Check memory_limit
		echo "Checking memory_limit for PHP in $file..."
		memory_limit=$(grep "memory_limit" $file | awk '{print $3}')
		# Extract the integer value from the memory limit
		int_memory_limit=$(echo $memory_limit | sed 's/[^0-9]*//g') 
		# Compare the extracted integer value with another value
		if [ -n "$int_memory_limit" ] ; then
			if [ "$int_memory_limit" -lt 1024 ] ; then
				echo "memory_limit is less than 1024M in $file, setting to 1024M..."
				sed -i 's/memory_limit = .*/memory_limit = 1024M/g' $file
			fi
		fi
	done
}

install_mibs() {
	echo "mibfile /usr/local/nagioslogserver/mibs/NAGIOS-ROOT-MIB.txt" >> /usr/share/snmp/snmp.conf
	echo "mibfile /usr/local/nagioslogserver/mibs/NAGIOS-NOTIFY-MIB.txt" >> /usr/share/snmp/snmp.conf
}

firewall() {
	if [ "$distro" != "Ubuntu" ] && [ "$distro" != "Debian" ]; then
		# Opens default Apache ports, NCPA port, and default master port
		open_tcp_ports 80 443 9200:9400 3515 3516 5544 2056 2057 5693 5546
		open_udp_ports 5544
	fi
}

configure_ldap() {

	# php-ldap already installed in prereqs
	if [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
		ldap_config="/etc/ldap/ldap.conf"
		ldap_dir="/etc/ldap"
		cacerts_dir="/etc/ldap/cacerts"
	else
		ldap_config="/etc/openldap/ldap.conf"
		ldap_dir="/etc/openldap"
		cacerts_dir="/etc/openldap/cacerts"
	fi

	# Set the permissions of the openldap configuration files/folders
	mkdir -p $cacerts_dir
	mkdir -p $ldap_dir/certs
	chown $apacheuser.$nagiosgroup $ldap_dir $ldap_dir/certs $cacerts_dir $ldap_config
	chmod 664 $ldap_config
	chmod 775 $ldap_dir $ldap_dir/certs $cacerts_dir

	echo '$config["ldap_dir"] = '"'$ldap_dir';" >> $proddir/application/config/config.local.php
	echo '$config["ldap_cacerts_dir"] = '"'$cacerts_dir';" >> $proddir/application/config/config.local.php

	# Edit line in ldap config
	sed -i 's/^TLS_CACERTDIR/#TLS_CACERTDIR/g' $ldap_config
	if [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
		echo "TLS_CACERTDIR $ldap_dir/cacerts" >> $ldap_config
	fi

}

selinux() {
	disable_selinux
}


daemons() {
	if [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
		if [ "$dist" == "ubuntu24" ] || [ "$dist" == "debian12" ]; then
			update-rc.d ntpsec defaults
		else
			update-rc.d ntp defaults
		fi
		update-rc.d "$httpd" defaults
		update-rc.d opensearch defaults
		update-rc.d logstash defaults

		if [ `command -v systemctl` ]; then
			systemctl restart ntp
			systemctl restart opensearch
			sleep 5
			systemctl restart rsyslog
		else
			service ntp restart
			service opensearch restart
			sleep 5
			service rsyslog restart
		fi
	else
		rc "$ntpd" "$httpd" opensearch
		sleep 5
		if [ "$dist" == "el8" ] || [ "$dist" == "el9" ]; then
			systemctl enable httpd.service
			systemctl enable opensearch.service
			systemctl enable logstash.service
			systemctl restart php-fpm.service
		fi
	fi

	# Cleanup GC Logs
	rm -rf /usr/local/nagioslogserver/opensearch/logs/gc*.log
	rm -rf /usr/local/nagioslogserver/logstash/logs/gc*.log
}


webroot() {
	# Save old web root page
	if [ -f /var/www/html/index.html ]; then
		mv /var/www/html/index.html /var/www/html/index.html.orig
	fi
	
	# Add a webroot if one doesn't exist
	if [ ! -f /var/www/html/index.php ]; then
		cp nagioslogserver/index.php /var/www/html/index.php
	fi
}

secondarypython() {

    if [ $(command -v python3.9) ]; then
    	# do nothing
    	:
    else
        wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz
        tar -xzf Python-3.9.0.tgz
        # Using a subshell to temporarily change directory
        (
            cd Python-3.9.0
            if [ "$distro" != "Ubuntu" ] && [ "$distro" != "Debian" ]; then
                yum install -y openssl-devel openssl
            elif [ "$distro" == "Ubuntu" ] || [ "$distro" == "Debian" ]; then
                apt-get install -y libssl-dev
            fi
            ./configure --prefix=/opt/python3.9 
            make && make install
        )

        ln -s /opt/python3.9/bin/python3.9 /usr/local/bin/python3.9
    fi

    python3.9 -m pip install --upgrade pip
    python3.9 -m pip install "openai<1.23.6"
	python3.9 -m pip install "anthropic<0.29.0"
	python3.9 -m pip install "mistralai<0.4.1"
    python3.9 -m pip install "urllib3<2.0"
}

configure_elasticsearch () {
	# Set OpenSearch clustering defaults
	elasticsearch_allow_reallocate
	systemctl restart logstash
}

##############################
### START THE INSTALLATION ###
##############################

fullinstall() {
	while [ -n "$1" ]; do
		case "$1" in
			-h | --help )
				usage
				exit
				;;
			-n | --non-interactive )
				INTERACTIVE="False"
				;;
			-d | --devel )
				DEVEL="True"
				;;
			-a | --add_node )
				ADDING_NODE="true"
				;;
			-m | --master | --manager )
				MANAGER_BASE_URL="$2"
				shift
				;;
			--node-name )
				NODE_NAME="$2"
				shift
				;;
			-k | --token )
				API_TOKEN="$3"
				shift
				;;
			-t | --ntp-server )
				NTP_SERVER="$2"
				shift
				;;
			* )
				usage >&2
				error "invalid command line syntax."
		esac
		shift
	done

	print_header "Nagios Log Server"
	
	get_cluster_info

	run_steps prereqs setup_local_syslog sourceguardian timezone nagioslogserver firewall backend install_mibs sudoers configure_ldap selinux test_cluster_connection configure_elasticsearch daemons webroot secondarypython

	#Reset signal handler to prevent error when main script exits
	trap - 0

	touch $backenddir/.installed

	print_footer "Nagios Log Server" "nagioslogserver" "${ADDING_NODE}"
	echo ""
}

log_it install.log fullinstall "$@"
exit 0
