#!/bin/bash
do {
	#////////////////////////////////////
	# DietPi Services Script
	#
	#////////////////////////////////////
	# Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com
	#
	# Info:
	# - Allows service control for all listed programs used in dietpi-software
	# - Disable removes the autostart from init.d and systemD. This allows DietPi to control program services below.
	#
	# Usage:
	# - /DietPi/dietpi/dietpi-services $AVAILABLE_OPTIONS
	#////////////////////////////////////
	setvar AVAILABLE_OPTIONS = ''
 - start/stop/restart/status (all services, known to DietPi)
 - start/stop/restart servicename (single service, SystemD)
 - systemd_controlled/dietpi_controlled (all services, known to DietPi)
 - enable/disable servicename (single service, SystemD)
 - enable/disable all (all services, known to DietPi)
 - mask/unmask servicename (single service, SystemD)''

	#Grab Inputs
	setvar INPUT_MODE = "$1"
	setvar INPUT_S2 = "$2"

	#Import DietPi-Globals ---------------------------------------------------------------
	source /DietPi/dietpi/func/dietpi-globals
	G_CHECK_ROOT_USER
	export G_PROGRAM_NAME='DietPi-Services'
	#Import DietPi-Globals ---------------------------------------------------------------

	setvar aSERVICE_NAME = ''(
		'cron'
		'transmission-daemon'
		'proftpd'
		'smbd'
		'nmbd'
		'nfs-kernel-server'
		'vsftpd'
		'apache2'
		'nginx'
		'lighttpd'
		'php5-fpm'
		'php7.0-fpm'
		'mysql'
		'mpd'
		'ympd'
		'minidlna'
		'noip2'
		'grasshopper'
		'dnsmasq'
		'pihole-FTL'
		'subsonic'
		'webiopi'
		'haproxy'
		'fail2ban'
		'openvpn'
		'isc-dhcp-server'
		'hostapd'
		'avahi-daemon'
		'shairport-sync'
		'squeezelite'
		'mopidy'
		#'mariadb' #: https://github.com/Fourdee/DietPi/issues/1000#issuecomment-307760517
		'redis-server'
		'emonhub'
		'netdata'
		'mumble-server'
		'emby-server'
		'plexmediaserver'
		'cuberite'
		'supervisor'
		'gogs'
		'qbittorrent'
		'syncthing'
		'syncthing-inotify'
		'rtorrent'
		'urbackupsrv'
		'sickrage'
		'roonbridge'
		'mosquitto'
		'networkaudiod'
		'node-red'
		'tomcat8'
		'rpimonitor'
		'openmediavault-engined'
		'blynkserver'
		'aria2'
		'yacy'
		'tonido'
		'icecast2'
		'darkice'
		'motioneye'
		'cups'
		'cloudprintd'
		'virtualhere'
		'sabnzbd'
		'spotify-connect-web'
		'couchpotato'
		'koel'
		'sonarr'
		'radarr'
		'plexpy'
		'jackett'
		'nzbget'
		'octoprint'
		'roonserver'
		'htpc-manager'
		'home-assistant'
		'openbazaar'
		#'dietpi-wifi-monitor' : https://github.com/Fourdee/DietPi/issues/1288#issuecomment-350653480
		'docker'
		'bdd'
		'minio'
		'gmrender'
		'nukkit'
		'gitea'
		'pi-spc'
		'raspotify'
		#'moode-worker'
		'voice-recognizer'
		'alsa-init'
	)

	# - User: read custom services file
	setvar FP_INCLUDE_SERVICES = ''/DietPi/dietpi/.dietpi-services_include''
	if test -f $FP_INCLUDE_SERVICES {

		while read line
		{

			setvar index = ${#aSERVICE_NAME[@]}
			setvar aSERVICE_NAME[$index]="$line"

		} < "$FP_INCLUDE_SERVICES"

	}

	#init
	setvar aSERVICE_AVAILABLE = '0'
	for ((i=0; i<${#aSERVICE_NAME[@]}; i++))
	do
		aSERVICE_AVAILABLE[$i]=0

	done

	#Check if service name is available on system.
	proc Populate_Available_Array {

		#Find dpkg program names
		dpkg --get-selections | awk '{print $1}' > "$FP_TEMP"

		for ((i=0; i<${#aSERVICE_NAME[@]}; i++))
		do

			if [ -f /etc/systemd/system/${aSERVICE_NAME[$i]}.service ] ||
				[ -f /lib/systemd/system/${aSERVICE_NAME[$i]}.service ]; then

				aSERVICE_AVAILABLE[$i]=1

			elif [ -f /etc/init.d/${aSERVICE_NAME[$i]} ]; then

				aSERVICE_AVAILABLE[$i]=1

			# - Check dpkg for matching packages.
			elif (( $(grep -ci -m1 "^${aSERVICE_NAME[$i]}$" "$FP_TEMP") )); then

				aSERVICE_AVAILABLE[$i]=1

			fi

		done

	}

	proc Print_Status {

		#$1 = Method
		#$2 = name
		#$3 = exit code

		#	NB: SystemD exit code 5 = not loaded/active, so dont trigger a failed result.

		#ok
		if (( $3 == 0 || $3 == 5 )) {

			G_DIETPI-NOTIFY 0 "$1 : $2"

		#failed
		} else {

			G_DIETPI-NOTIFY 1 "$1 : $2"

		}

	}

	#$1 = mode (eg: start/stop/restart)
	proc Set_Running_State {

		local target_state="$1"

		#????????????????????????????????????????????????????????????????????????
		# Although this allows for simple service control without using SystemD, we really should convert these to SystemD services. To keep everything consistent, clean, and obtain a correct exit code.
		#DietPi: Non-service based control for specific dietpi-software installed programs.
		# - Start order first
		setvar index = '0'
		setvar aDIETPISERVICE_FP = ''()
		setvar aDIETPISERVICE_NAME = ''()
		setvar aDIETPISERVICE_NAME[$index]='BruteFIR';setvar aDIETPISERVICE_FP[$index]='/var/lib/dietpi/dietpi-software/services/brutefir.service';((index++));
		setvar aDIETPISERVICE_NAME[$index]='JackD';setvar aDIETPISERVICE_FP[$index]='/var/lib/dietpi/dietpi-software/services/jackd.service';((index++));
		setvar aDIETPISERVICE_NAME[$index]='Jconvolver';setvar aDIETPISERVICE_FP[$index]='/var/lib/dietpi/dietpi-software/services/jconvolver.service';((index++));

		for ((i=0; i<${#aDIETPISERVICE_NAME[@]}; i++))
		do

			if [ -f ${aDIETPISERVICE_FP[$i]} ]; then

				G_DIETPI-NOTIFY -2 "${aDIETPISERVICE_NAME[$i]}"

				${aDIETPISERVICE_FP[$i]} $target_state &> /dev/null
				Print_Status $target_state ${aDIETPISERVICE_NAME[$i]} $?

			fi

		done

		unset aDIETPISERVICE_NAME
		unset aDIETPISERVICE_FP
		#????????????????????????????????????????????????????????????????????????

		#### ALLO Special ####
		setvar aALLO_EXCLUDED_SERVICES_DURING_STOP = ''(
			'apache2'
			'nginx'
			'lighttpd'
			'php5-fpm'
			'php7.0-fpm'
			'mysql'
			'avahi-daemon'
		)
		#### ALLO Special ####

		#Linux: installed services
		for ((i=0; i<${#aSERVICE_NAME[@]}; i++))
		do

			#### ALLO Special ####
			# - Allo web interface image: Exclude stop on aALLO_EXCLUDED_SERVICES_DURING_STOP service list
			if [ -d /var/www/allo ] && [ "$target_state" = "stop" ]; then

				for ((j=0; j<${#aALLO_EXCLUDED_SERVICES_DURING_STOP[@]}; j++))
				do

					if [ "${aSERVICE_NAME[$i]}" = "${aALLO_EXCLUDED_SERVICES_DURING_STOP[$j]}" ]; then

						aSERVICE_AVAILABLE[$i]=0
						break

					fi

				done

			fi
			#### ALLO Special ####

			#Apply
			if (( ${aSERVICE_AVAILABLE[$i]} == 1 )); then

				G_DIETPI-NOTIFY -2 "${aSERVICE_NAME[$i]}"

				systemctl $target_state ${aSERVICE_NAME[$i]} &> /dev/null

				Print_Status $target_state ${aSERVICE_NAME[$i]} $?

			fi

		done

		unset aALLO_EXCLUDED_SERVICES_DURING_STOP

		#????????????????????????????????????????????????????????????????????????
		# Although this allows for simple service control without using SystemD, we really should convert these to SystemD services. To keep everything consistent, clean, and obtain a correct exit code.
		#DietPi: Non-service based control for specific dietpi-software installed programs.
		# - Start prority last
		setvar index = '0'
		setvar aDIETPISERVICE_FP = ''()
		setvar aDIETPISERVICE_NAME = ''()
		setvar aDIETPISERVICE_NAME[$index]='RaspimJpeg';setvar aDIETPISERVICE_FP[$index]='/var/lib/dietpi/dietpi-software/services/raspimjpeg.service';((index++));
		setvar aDIETPISERVICE_NAME[$index]='Deluge';setvar aDIETPISERVICE_FP[$index]='/var/lib/dietpi/dietpi-software/services/deluge.service';((index++));
		setvar aDIETPISERVICE_NAME[$index]='SqueezeBox Server';setvar aDIETPISERVICE_FP[$index]='/var/lib/dietpi/dietpi-software/services/squeezeboxserver.service';((index++));

		for ((i=0; i<${#aDIETPISERVICE_NAME[@]}; i++))
		do

			if [ -f ${aDIETPISERVICE_FP[$i]} ]; then

				G_DIETPI-NOTIFY -2 "${aDIETPISERVICE_NAME[$i]}"

				${aDIETPISERVICE_FP[$i]} $target_state &> /dev/null
				Print_Status $target_state ${aDIETPISERVICE_NAME[$i]} $?

			fi

		done

		unset aDIETPISERVICE_NAME
		unset aDIETPISERVICE_FP
		#????????????????????????????????????????????????????????????????????????

		echo -e ""

		#Apply process tool settings
		if test $target_state = "start" ||
			test $target_state = "restart" {

			/DietPi/dietpi/dietpi-process_tool 1

		}

	}

	setvar FP_TEMP = ""/tmp/.dietpi-services_installed""

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main
	#/////////////////////////////////////////////////////////////////////////////////////
	#Info
	G_DIETPI-NOTIFY 3 DietPi-Services $INPUT_MODE

	#Obtain an array of available services installed on system.
	Populate_Available_Array

	#-----------------------------------------------------------------------------------
	#dietpi_controlled/systemd_controlled
	if test $INPUT_MODE = 'dietpi_controlled' ||
		test $INPUT_MODE = 'systemd_controlled' {

		setvar SYSTEMD_CMD = ''disable''

		if test $INPUT_MODE = "systemd_controlled" {

			setvar SYSTEMD_CMD = ''enable''

		}

		for ((i=0; i<${#aSERVICE_NAME[@]}; i++))
		do

			#Apply
			if (( ${aSERVICE_AVAILABLE[$i]} == 1 )); then

				G_DIETPI-NOTIFY -2 "${aSERVICE_NAME[$i]}"

				systemctl $SYSTEMD_CMD ${aSERVICE_NAME[$i]} &> /dev/null

				Print_Status $INPUT_MODE ${aSERVICE_NAME[$i]} $?

			fi

		done

		systemctl daemon-reload &> /dev/null

		echo -e ""

	#-----------------------------------------------------------------------------------
	#mask/unmask/enable/disable
	} elif test $INPUT_MODE = "enable" ||
		test $INPUT_MODE = "disable" ||
		test $INPUT_MODE = "unmask" ||
		test $INPUT_MODE = "mask" {

		#Switch to mask, as DietPi_Controlled uses disable to take over from SystemD
		setvar SYSTEMD_CMD = ''mask''
		if test $INPUT_MODE = "enable" ||
			test $INPUT_MODE = "unmask" {

			setvar SYSTEMD_CMD = ''unmask''

		}

		# - Process ALL known services
		if test $INPUT_S2 = 'all' {

			if test $INPUT_MODE = "disable" ||
				test $INPUT_MODE = "mask" {

				echo -e ""
				Set_Running_State stop

			}

			for ((i=0; i<${#aSERVICE_NAME[@]}; i++))
			do

				if (( ${aSERVICE_AVAILABLE[$i]} )); then


					G_DIETPI-NOTIFY 0 "$INPUT_MODE $INPUT_S2: ${aSERVICE_NAME[$i]}"
					systemctl $SYSTEMD_CMD ${aSERVICE_NAME[$i]}

				fi

			done


		# - Process user defined single entry via cmd input
		} else {

			systemctl stop $INPUT_S2

			systemctl $SYSTEMD_CMD $INPUT_S2
			if (( $? == 0 )) {

				G_DIETPI-NOTIFY 0 "$INPUT_MODE $INPUT_S2"

			} else {

				G_DIETPI-NOTIFY 1 "$INPUT_MODE $INPUT_S2"

			}

		}

		systemctl daemon-reload &> /dev/null

		if test $INPUT_MODE = "unmask" ||
			test $INPUT_MODE = "enable" {

			echo -e ""
			Set_Running_State start

		}

		echo -e ""

	#-----------------------------------------------------------------------------------
	#status
	} elif test $INPUT_MODE = "status" {

		for ((i=0; i<${#aSERVICE_NAME[@]}; i++))
		do

			#Apply
			if (( ${aSERVICE_AVAILABLE[$i]} == 1 )); then

				STATUS="${aSERVICE_NAME[$i]}\t$(systemctl status ${aSERVICE_NAME[$i]} | grep -m1 'Active' | cut -c12-)"

				if [[ "$STATUS" =~ .*'failed'.* ]]; then

					G_DIETPI-NOTIFY 1 "$STATUS"
					systemctl status "${aSERVICE_NAME[$i]}" -l --no-pager

				elif [[ "$STATUS" =~ .*'inactive'.* ]]; then

					G_DIETPI-NOTIFY 2 "$STATUS"

				else

					G_DIETPI-NOTIFY 0 "$STATUS"

				fi

			fi

		done

		echo -e ""

	#-----------------------------------------------------------------------------------
	#start/stop/restart
	} elif test $INPUT_MODE = "start" ||
		test $INPUT_MODE = "stop" ||
		test $INPUT_MODE = "restart" {

			#Single use case, basically a alias for systemD
			if test -n $INPUT_S2 {

				systemctl $INPUT_MODE $INPUT_S2 &> /dev/null
				if (( $? == 0 )) {

					G_DIETPI-NOTIFY 0 "$INPUT_MODE $INPUT_S2"

				} else {

					G_DIETPI-NOTIFY 1 "$INPUT_MODE $INPUT_S2"

				}

				echo -e ""

			#All services controlled
			} else {

				# Control ownCloud and Nextcloud maintenance mode:
				if test $INPUT_MODE = "stop" || test $INPUT_MODE = "restart" {

					grep -q "'maintenance' => false," /var/www/owncloud/config/config.php &> /dev/null && G_RUN_CMD occ maintenance:mode --on
					grep -q "'maintenance' => false," /var/www/nextcloud/config/config.php &> /dev/null && G_RUN_CMD ncc maintenance:mode --on

				}

				Set_Running_State $INPUT_MODE

				# Control ownCloud and Nextcloud maintenance mode:
				if test $INPUT_MODE = "restart" || test $INPUT_MODE = "start" {

					grep -q "'maintenance' => true," /var/www/owncloud/config/config.php &> /dev/null && G_RUN_CMD occ maintenance:mode --off
					grep -q "'maintenance' => true," /var/www/nextcloud/config/config.php &> /dev/null && G_RUN_CMD ncc maintenance:mode --off

				}

			}

	#-----------------------------------------------------------------------------------
	#Invalid command
	} else {
		G_DIETPI-NOTIFY 2 "Invalid command\e[0m\nAvailable commands:\n$AVAILABLE_OPTIONS\n"
	}
	#-----------------------------------------------------------------------------------
	rm $FP_TEMP
	unset aSERVICE_NAME
	unset aSERVICE_AVAILABLE
	#-----------------------------------------------------------------------------------
	exit
	#-----------------------------------------------------------------------------------
}