#!/bin/sh -ue

LANG=POSIX
SD_BOOTED=sd_booted
SYSTEMCTL=systemctl
INITDIR=/etc/rc.d/init.d

alterator_api_version=1
. alterator-sh-functions
. alterator-service-functions

# directory with desktop-files
DESKTOPDIR=/etc/alterator/services

NODISPLAY_SERVICES='ahttpd|alteratord'

list_systemd_units()
{
	local unit_type="$1"; shift
	$SYSTEMCTL list-unit-files -t "$unit_type" --full --no-legend --no-pager | \
		sed -r -n "s;^(.+\.$unit_type)[[:blank:]]+(enabled|disabled).*$;\1;p" | \
		while read unit; do
			# Drop all dublicates

			# 'head -1' is needed for 'socket' units:
			# something wrong with them, property can be listed several times
			id="$($SYSTEMCTL show --no-pager -p Id "$unit" | cut -f2 -d= | head -1)"

			# Skip if Id does not match unit name
			[ "$unit" != "$id" ] || echo "$unit"
		done
}

services_list()
{
	if $SD_BOOTED; then
		local services= sockets=

		services="$(list_systemd_units service)"
		sockets="$(list_systemd_units socket)"

		printf "%s\n%s\n" "$services" "$sockets" | sort
	else
		local script=
		local tmp=
		for script in $(find -L "$INITDIR" -mindepth 1 -maxdepth 1 \
				-type f -perm /0111 \
				! -name '*.rpm*' ! -name '*~' -printf '%f\n' | sort); do
			# Ensure that it is init script
			$CHKCONFIG --add "$script" >/dev/null 2>&1 || continue
			# Ensure that script have usage at least
			tmp="$($SERVICE "$script" 2>&1)" ||:
			[ -n "$tmp" ] || continue
			echo "$script"
		done
	fi
}

get_services(){
	services_list | egrep -v "^($NODISPLAY_SERVICES)"
}

# Get status information: stopped|running
service_status(){
	service_control "$1" is-active >/dev/null 2>&1 &&
		echo -n "`_ "running"`" ||
		echo -n "`_ "stopped"`"
}

# is service switched on for current runlevel?
chkconfig_status(){
	service_control "$1" is-enabled >/dev/null 2>&1 &&
		echo on ||
		echo off
}

# get description from script header
filter_description(){
	awk 'BEGIN { is_desc=0; text="" }
/^#[[:space:]]*description:/ {
    is_desc=1
    gsub(/description:[[:space:]]*/,"")
}
/^#/ {
    if (is_desc == 1) {
	gsub(/^#[[:space:]]*/,"")
	if (gsub(/[[:space:]]*\\$/,"") < 1) {
	    is_desc=0
	}
	text=text " " $0;
	if (is_desc == 0) {
	    print text
	    exit
	}
    }
}'
}

get_description()
{
	local srv="$1"; shift
	local sd_booted=
	local dt=

	if $SD_BOOTED; then
		sd_booted=1
		dt=$DESKTOPDIR/${srv%.*}.desktop
	else
		dt=$DESKTOPDIR/$srv.desktop
	fi

	if [ -f "$dt" ]; then
		alterator-dump-desktop -v lang="$in_language" -v out="Comment" "$dt"
		return
	fi
	if [ -n "$sd_booted" ]; then
		# 'head -1' is needed for 'socket' units:
		# something wrong with them, property can be listed several times
		$SYSTEMCTL show --no-pager -p Description "$srv" | cut -f2 -d= | head -1
	else
		cat "$INITDIR/${srv##*/}" | filter_description
	fi
}

on_message()
{
	case "$in_action" in
		list)
			if [ "$in__objects" != "/" ]; then
				local status=$(service_status "$in__objects")
				write_enum_item "dontchange" "`_ "do not change"`"
				if [ "$status" != "$(_ "running")" ]; then write_enum_item "start"   "`_ "start"`"; fi
				if [ "$status" != "$(_ "stopped")" ]; then write_enum_item "stop"    "`_ "stop"`"; fi
				if [ "$status" != "$(_ "stopped")" ]; then write_enum_item "restart" "`_ "restart"`"; fi
			else
				for srv in $(get_services); do
					write_enum_item "$srv"
				done
			fi
		;;
	
	read)
		local srv=$in_name
		write_string_param "name"   "$srv"
		write_string_param "status" "$(service_status "$srv")"
		write_bool_param   "chkconfig_status" "$(chkconfig_status "$srv")"
		write_string_param "description" "$(get_description "$srv")"
	    ;;

	write)
		local srv="$in_name"
		if [ "$in_change_status" == "start" ]; then
			service_control "$srv" start
		fi
		if [ "$in_change_status" == "stop" ]; then
			service_control "$srv" stop
		fi
		if [ "$in_change_status" == "restart" ]; then
			service_control "$srv" restart
		fi

		if test_bool "${in_chkconfig_status:-}"; then
			service_control "$srv" on
		else
			service_control "$srv" off
		fi
		sleep 1
		;;
esac
}

message_loop
