#!/bin/sh -e

LANG=POSIX
CHKCONFIG=/sbin/chkconfig
SERVICE=/sbin/service
INITDIR=/etc/rc.d/init.d
RUNLEVEL=$(/sbin/runlevel | cut -c3)

alterator_api_version=1
. alterator-sh-functions

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

# find all scripts in $INITDIR
find_scripts(){
    find -L "$INITDIR" -mindepth 1 -maxdepth 1 \
      -type f -perm +0111 ! -name 'ahttpd' ! -name 'configd' \
         ! -name '*.rpm*' ! -name '*~' -printf '%f\n' | sort
}

get_services(){
  for srv in $(find_scripts); do
    # if service is not in chkconfig try to add it and switch off
    if [ -z "$($CHKCONFIG --list $srv 2>/dev/null)" ]; then
      $CHKCONFIG --add "$srv" &> /dev/null &&
        $CHKCONFIG "$srv" off &> /dev/null
    fi

    # if we can't add service to chkconfig - skip service
    if [ -z "$($CHKCONFIG --list $srv 2>/dev/null)" ]; then
      continue
    fi
    echo "$srv"
  done
}



# Get usage string from service script.
# Smthing like "Usage: xinetd {start|stop|status|reload}"
script_usage(){ # (name)
  $SERVICE "$1" 2>&1
}

# Get status information: stopped|running|unknown
# Usage string must be provided
script_status(){ # (srv usage)
  if ! echo -n "$2" | egrep -q "(\{|\|)status(\||\})"; then
    echo -n "`_ "unknown"`"; return
  fi
  local unf_status=$($SERVICE $1 status 2>/dev/null)
  case "$unf_status" in
   *"is stopped"*) echo -n "`_ "stopped"`" ;;
   *"is dead"*)    echo -n "`_ "stopped"`" ;;
   *"is running"*) echo -n "`_ "running"`" ;;
   *)              echo -n "`_ "unknown"`" ;;
  esac
}

# Is script supports start and stop commands: #t|#f
# Usage string must be provided
is_switchable(){ # (usage)
  local ret="off"
#  [[ "$1" =~ "(\{|\|)start(\||\})" ]] &&
#    [[ "$1" =~ "(\{|\|)stop(\||\})" ]] &&
#      ret="on"
   echo "$1" | egrep -q "(\{|\|)start(\||\})" &&
     echo "$1" | egrep -q "(\{|\|)stop(\||\})" &&
       ret="on"

  echo -n "$ret"
}


# is service switched on for current runlevel?
chkconfig_status(){
  local ret="off"
#  [[ "$($CHKCONFIG --list $1)" =~ "${RUNLEVEL}:on" ]] && ret="on"
  echo "$($CHKCONFIG --list $1)" | grep -q "${RUNLEVEL}:on" && ret="on"
  echo "$ret"
}

# 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
	}
    }
}'
}





on_message()
{

    case "$in_action" in
        list)
	    if [ "$in__objects" != "/" ]; then
	      local usage=$(script_usage $in__objects)
	      local status=$(script_status "$in__objects" "$usage")
	      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
#	        local usage=$(script_usage $srv)
#	        local status=$(script_status "$srv" "$usage")
#	        echo -n "(\"$srv\" status $status) "
	        write_enum_item "$srv"
	      done
	    fi
	;;
	

	read)
	    # service must be in chkconfig
	    local srv=$in_name
	    if [ "$srv" != "/" ] &&
		$CHKCONFIG --list "$srv" &>/dev/null; then

		local usage="$(script_usage "$srv")"
		write_string_param "name"   "$srv"
		write_string_param "status" "$(script_status "$srv" "$usage")"
		write_bool_param   "chkconfig_status" "$(chkconfig_status "$srv")"
		write_string_param "switchable" "$(is_switchable "$usage")"
		local dt=$DESKTOPDIR/$srv.desktop
		if [ -f "$dt" ]; then
		  write_string_param description \
		    "$(alterator-dump-desktop -v lang="$in_language" -v out="Comment" "$dt")"
		else
		  write_string_param description \
		    "$(cat "$INITDIR/${srv##*/}" | filter_description)"
		fi
	    fi
	    ;;

	write)
	    local srv="$in_name"
	    if [ "$srv" != "/" ] &&
	        $CHKCONFIG --list "$srv" &>/dev/null; then

		if [ "$in_change_status" == "start" ]; then
		  $SERVICE $srv start &> /dev/null
		fi
		if [ "$in_change_status" == "stop" ]; then
		  $SERVICE $srv stop &> /dev/null
		fi
		if [ "$in_change_status" == "restart" ]; then
		  $SERVICE $srv restart &> /dev/null
		fi
		
		if test_bool "$in_chkconfig_status"; then
		  $CHKCONFIG $srv on &> /dev/null
		else
		  $CHKCONFIG $srv off &> /dev/null
		fi
		sleep 1
	    fi
	    ;;
        esac
}

message_loop
