#!/bin/sh
#
# Copyright:: Copyright 2020 Chef Software, Inc.
# Author:: Salim Afiune <afiune@chef.io>
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

set -eo pipefail

PROGNAME=$(basename "$0")
PRODUCTNAME="Chef Workstation App"
SERVICENAME="io.chef.chef-workstation.app"
PLISTFILE="${SERVICENAME}.plist"

usage() {
  cat <<DOC
Usage: ${PROGNAME} <subcommand>

Controls the ${PRODUCTNAME} launcher behavior for macOS systems.

Subcommands:
    show             Show launchd information about the ${PRODUCTNAME} service.
    load             Bootstraps the ${PRODUCTNAME} service.
    remove           Removes the ${PRODUCTNAME} service.
    startup <state>  Enable or disable the ${PRODUCTNAME} to start at boot. (default: enable)
DOC
}

usage_startup() {
  cat <<DOC
Usage: ${PROGNAME} startup <enable|disable>

Enable or disable the ${PRODUCTNAME} to start at boot. (default: enable)

Arguments:
    enable   Enable the ${PRODUCTNAME} to start at boot.
    disable  Disable the ${PRODUCTNAME} to start at boot.
DOC
}

main()
{
  if ! is_darwin; then
    error_exit "Launcher is only available for macOS systems"
  fi

  if [ $# -eq 0 ]; then
    usage
    exit 1
  fi

  case "$1" in
    "-h"|"--help")
      usage
      ;;
    "show")
      launchctl_show
      ;;
    "load")
      launchctl_load
      ;;
    "remove")
      launchctl_remove
      ;;
    "startup")
      startup "${2:-enable}"
      ;;
    *)
      error_exit "invalid option '$1'.\\nTry '--help' for more information."
  esac
}

error_exit()
{
  echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
  exit 1
}

is_darwin()
{
  uname -v | grep "^Darwin" >/dev/null 2>&1
}

startup()
{
  case "$1" in
    "-h"|"--help")
      usage_startup
      ;;
    "disable")
      rm -f "$HOME/Library/LaunchAgents/${PLISTFILE}"
      ;;
    "enable")
      if [ ! -d "$HOME/Library/LaunchAgents" ]; then
        mkdir "$HOME/Library/LaunchAgents"
      fi
      cp "/Applications/Chef Workstation App.app/Contents/Resources/assets/${PLISTFILE}" "$HOME/Library/LaunchAgents/."
      ;;
    *)
      error_exit "invalid startup state '$1'.\\nValid states are 'enable' or 'disable'.\\nTry '--help' for more information."
  esac

}

launchctl_load()
{
  if [ ! -d "/Applications/Chef Workstation App.app/Contents" ]; then
    error_exit "${PRODUCTNAME} not found in /Applications folder. The application needs to be installed first."
  fi

  launchctl_remove

  # we let launchd to process the removal of the service
  sleep 1

  startup "enable"
  ( cd "$HOME/Library/LaunchAgents" || error_exit "unable to enter LaunchAgents directory"
    launchctl load ${PLISTFILE}
  )
}

launchctl_remove()
{

  loggedInUser=$( ls -l /dev/console | awk '{print $3}' )

  # Get loggedInUser ID
  userID=$( id -u "$loggedInUser" )

  if launchctl print "gui/$userID/$SERVICENAME" >/dev/null 2>&1; then
    launchctl bootout "gui/$userID" "$HOME/Library/LaunchAgents/${PLISTFILE}"
  fi

  if [ -f "$HOME/Library/LaunchAgents/${PLISTFILE}" ]; then
    rm -rf "$HOME/Library/LaunchAgents/${PLISTFILE}"
  fi
}

launchctl_show()
{
  if launchctl list "$SERVICENAME" >/dev/null 2>&1; then
    launchctl list "$SERVICENAME"
  else
    error_exit "$PRODUCTNAME is not yet loaded.\\nTry using the subcommand 'load'."
  fi
}

main "$@"
