#!/bin/dash
# Convenience service wrapper
# (C) James Budiono 2014
# License: GPL Version 3 or later.

### configuration
SERVICE_DIR=/etc/init.d
RESERVED=":S01logging:S40network:README.md:"
[ -e /etc/servicemanager ] && . /etc/servicemanager	# override default settings
[ $(id -u) -ne 0 ] && exec su -c "$0 $*"

### check for reserved services which we don't want to show
# $1-service file
is_reserved() {
	local p=${1##*/}
	case "$RESERVED" in 
		*:${p}:*) return 0
	esac
	return 1
}

# $1-service filename, output: SNAME=service name
get_service_name() {
	case ${1#$SERVICE_DIR/} in
		*-*) SNAME=${1#*-} ;;
		S??*) SNAME=${1#S??} ;;
		rc.*) SNAME=${1#rc.} ;;
		*) SNAME=${1} ;;
	esac
}

### helper
#$1-service-file,$2-service-name, output DESC and HELP
get_service_description() {
	local p
	DESC="" HELP=""
	
	# attempt to find description and help from service file itself
	while read -r p; do
		case "$p" in
			*[Dd]escription:*) DESC=${p#*: } ;;
			*[Hh]elp*) HELP=${p#*: } ;;
		esac
	done << EOF
$(grep -iE '^#.*(description:|help:)' $SERVICE_DIR/$1 2>/dev/null)
EOF

	# legacy way of getting description and help
	if [ -z "$DESC" ]; then
		OIFS=$IFS; IFS=";"
		for p in $SERVICE_DESC; do
			if [ $2 = "${p%%|*}" ]; then
				DESC=${p##*|}
				break
			fi
		done
		
		for p in $SERVICE_HELP; do
			if [ $2 = "${p%%|*}" ]; then
				HELP=${p##*|}
				break
			fi
		done
		IFS=$OIFS
	fi
}

# $1-service name
find_service() {
	# first try: *-* pattern
	SERVICE=$(echo $SERVICE_DIR/*-$1)
	[ -e "$SERVICE" ] && return
	# 2nd try: S??* pattern
	SERVICE=$(echo $SERVICE_DIR/S??$1)
	[ -e "$SERVICE" ] && return
	# 3rd try: rc.* pattern
	SERVICE=$(echo $SERVICE_DIR/rc.$1)
	[ -e "$SERVICE" ] && return
	# last try: actual name
	SERVICE=$SERVICE_DIR/$1
	[ -e "$SERVICE" ] && return
	echo "$1" is not a service.
	exit 1
}

### main
case "$1" in
	--help|-h|"")
		echo "Usage: ${0##*/} --help | --list | --status-all | --enable service |"
		echo "       --disable service | service [command|--full-restart]"
		echo "       Usual service commands: start stop status restart"
		;;
	--list) 
		for sfile in $SERVICE_DIR/*; do
			disabled="(disabled)"
			test -x $sfile && disabled=""		
			sfile=${sfile#$SERVICE_DIR/}
			is_reserved $sfile && continue
			get_service_name $sfile
			get_service_description $sfile $SNAME
			printf "%s %s\n  %s\n" "$SNAME" "$disabled" "$DESC"
		done
		;;
	--status-all)
		for sfile in $SERVICE_DIR/*; do
			sfile=${sfile#$SERVICE_DIR/}
			is_reserved $sfile && continue
			sh $SERVICE_DIR/$sfile status
		done
		;;
	--enable)
		shift
		find_service "$1" &&
		get_service_name $SERVICE &&
		chmod +x $SERVICE &&
		echo $SNAME enabled
		;;
	--disable)
		shift
		find_service "$1" &&
		get_service_name $SERVICE &&
		chmod -x $SERVICE &&
		echo $SNAME disabled
		;;
	*) 
	find_service "$1"; shift
	case "$1" in
		--full-restart)
			sh $SERVICE stop
			sleep 1
			sh $SERVICE start
			;;
		"")
			sh $SERVICE status
			;;
		*)
			sh $SERVICE "$@"
			;;
	esac
	;;
esac
