#!/bin/bash

# Arguments: the name of a service
# Return value: 0 if it exists, 1 if not
service_exists ()
{
   SERVICES=($(ls -1 /home/user/services/))
   for SERV in "${SERVICES[@]}"; do
      if [[ "$1" == "${SERV}" ]]; then
         return "0"
      fi
   done
   return "1"
}

# Arguments: the name of a service
# Return value: 0 if it's running, 1 if not
service_active ()
{
   if [[ ! -f /home/user/services/$1/status ]]; then # If the service status file doesn't exist, assume it's not running
      sudo -u $1 bash -c "echo -n '0' > /home/user/services/$1/status" # bash reasons..
      return "1"
   fi

   ACTIVE="$(cat /home/user/services/$1/status)"
   if [[ "${ACTIVE}" == "1" ]]; then
      return "0"
   fi
   return "1"
}

# Arguments: none
# Returns: 0
# Prints all services
list_services ()
{
   ls -1 /home/user/services/
   return "0"
}

# Arguments: the name of a service
# Return value: 1 if the service does not exist, 0 otherwise
start_service ()
{
   if service_exists "$1"; then
      if ! service_active "$1"; then
         sudo -u $1 /home/user/services/$1/start.sh
         sudo -u $1 bash -c "echo -n '1' > /home/user/services/$1/status"
         return "0"
      fi
      return "0"
   fi
   return "1"
}

# Arguments: the name of a service
# Return value: 1 if the service does not exist, 0 otherwise
stop_service ()
{
   if service_exists "$1"; then
      if service_active "$1"; then
         sudo -u $1 /home/user/services/$1/stop.sh
         sudo -u $1 bash -c "echo -n '0' > /home/user/services/$1/status"
         return "0"
      fi
      return "0"
   fi
   return "1"
}

# Arguments: the name of a service
# Return value: 1 if the service does not exist, 0 otherwise
restart_service ()
{
   # Yes, this is just a wrapper to call start_service() and stop_service().. but it works
   # No need to validate if $1 is a service, because stop_service and start_service do this already
   stop_service "$1"
   if [[ "$?" == "1" ]]; then
      return "1"
   else
      sleep "1"
      start_service "$1"
      return "$?"
   fi
}

# Arguments: none
# Return value: none
restart_all_services ()
{
   SERVICES=($(list_services))
   for SERV in "${SERVICES[@]}"; do
      restart_service "${SERV}"
   done
}

# Arguments: none
# Return value: none
start_all_services ()
{
   SERVICES=($(list_services))
   for SERV in "${SERVICES[@]}"; do
      start_service "${SERV}"
   done
}

# Arguments: none
# Return value: none
stop_all_services ()
{
   SERVICES=($(list_services))
   for SERV in "${SERVICES[@]}"; do
      stop_service "${SERV}"
   done
}

# Arguments: A number, a string, and a string
# Prints string #1 and exits with code 0 if the number is 0
# Else, it prints string #2 and exits with code 1
exit_code ()
{
   if [[ "$1" == "0" ]]; then
      echo "$2"
      exit "0"
   else
      echo "$3"
      exit "1"
   fi
}

# Arguments: none
# Return value: none
list_active_services ()
{
   SERVICES=($(list_services))
   for SERV in "${SERVICES[@]}"; do
      if service_active "${SERV}"; then
         echo "${SERV}"
      fi
   done
}

# Arguments: none
# Return value: none
list_inactive_services ()
{
   SERVICES=($(list_services))
   for SERV in "${SERVICES[@]}"; do
      if ! service_active "${SERV}"; then
         echo "${SERV}"
      fi
   done
}

# Arguments: none
# Return value: none
service_status_all ()
{
   SERVICES=($(list_services))
   for SERV in "${SERVICES[@]}"; do
      service_active "${SERV}"
      if [[ "$?" == "0" ]]; then
         echo "Service '${SERV}' is currently running"
      else
	     echo "Service '${SERV}' is currently not running"
      fi
   done
}

case "$1" in
   start)
      start_service "$2"
      exit_code "$?" "Started service '$2'" "Failed to start service '$2'"
   ;;

   stop)
      stop_service "$2"
      exit_code "$?" "Stopped service '$2'" "Failed to stop service '$2'"
   ;;

   restart)
      restart_service "$2"
      exit_code "$?" "Restarted service '$2'" "Failed to restart service '$2'"
   ;;

   status)
      if service_exists "$2"; then
         service_active "$2"
         exit_code "$?" "Service '$2' is currently running" "Service '$2' is currently not running"
      fi
      exit_code "1" "" "No such service '$2'"
   ;;

   startall)
      start_all_services
   ;;

   stopall)
      stop_all_services
   ;;

   restartall)
      restart_all_services
   ;;

   listall)
      list_services
   ;;

   listactive)
      list_active_services
   ;;

   listinactive)
      list_inactive_services
   ;;

   statusall)
      service_status_all
   ;;
   
   *)
      exit_code "1" "" "Usage:
$0 (start|stop|restart|status|statusall|startall|stopall|restartall|listall|listactive|listinactive) [service]
   
Options:
   start <service>   - Start a service
   stop <service>    - Stop a service
   restart <service> - Restart a service
   status <service>  - Get the status of a service
   statusall         - Get the status of all services
   startall          - Start all services
   stopall           - Stop all services
   restartall        - Restart all services
   listall           - List all services
   listactive        - List all active services
   listinactive      - List all inactive services"
   ;;
esac
