#!/bin/bash

TVD_SYSV_DIR='/etc/init.d'
TVD_SYSV_SRC='teamviewerd.sysv'
TVD_SYSV_FILE='teamviewerd'
TVD_SYSV_PATH="$TVD_SYSV_DIR/$TVD_SYSV_FILE"

TVD_SYSD_DIR='/etc/systemd/system'	# overrides /lib/systemd/system  /usr/lib/systemd/system
TVD_SYSD_FILE='teamviewerd.service'
TVD_SYSD_PATH="$TVD_SYSD_DIR/$TVD_SYSD_FILE"

function DistroDerivate()
{
  local result=''

  if egrep -i -e "CentOS|Red Hat|Scientific" /etc/issue &> /dev/null; then
    result="RHEL"
  fi

  echo $result
}

function UpstartType()
{
  local upType="$(DistroDerivate)"

  if [ -z "$upType" ]; then
    upType=$TV_PKGTYPE

    if [ "$TV_PKGTYPE" == TAR_IN ]; then
      upType='DEB'
      [ -x /sbin/runlevel ] && /sbin/runlevel | grep -q 5 && upType='RPM'
    fi
  fi

  echo $upType
}

TVD_UPST_DIR='/etc/init'
TVD_UPST_SRC="teamviewerd.$(UpstartType).conf"
TVD_UPST_FILE='teamviewerd.conf'
TVD_UPST_PATH="$TVD_UPST_DIR/$TVD_UPST_FILE"

TVD_SEL_POLICY="$TV_SCRIPT_DIR/teamviewerd.pp"
TVD_SEL_MODULE="teamviewerd"


function installLog()
{
  if [ "$TV_PACKAGE_INSTALL" = "yes" ]; then
    cat >> "$TV_INSTALL_LOG"
  else
    tee -a "$TV_INSTALL_LOG"
  fi
}

function installLogHeader()
{
  local action="$1"

  [ -e "$TV_INSTALL_LOG" ] && echo
  date
  echo "Action: $action"
}

function detectUpstart
{
  local forcesysv='/opt/teamviewer/config/systemv'
  [ -f $forcesysv ]	&& return 1	# override detection
  cmdExists initctl	|| return 1	# no root required
  isSuperUser		|| return 0	# if root, check more

  # expect init version to contain 'upstart', and version not to be 0.3.9 (used on Ubuntu 8.04 and 9.04)
  local upstart=$( getInitCmd | grep init > /dev/null && init --version 2>/dev/null | grep upstart )
  [ -n "$upstart" ] && [[ "$upstart" != *0.3.* ]]
}

function detectSystemD
{
  local forcesysv='/opt/teamviewer/config/systemv'
  [ -f $forcesysv ]	&& return 1	# override detection
  cmdExists systemctl	|| return 1	# no root required
  isSuperUser		|| return 0	# if root, check more

  local systemd=$( readlink -e $(getInitCmd) 2>/dev/null | grep systemd )
  [ -n "$systemd" ]
}

function installDaemon()
{
  exec 2>&1
  
  local dtype='V'
  detectSystemD && dtype='D'
  detectUpstart && dtype='U'

  [ $dtype = 'V' ] && installDaemonSysV			| installLog
  [ $dtype = 'D' ] && installDaemonSystemD		| installLog
  [ $dtype = 'U' ] && installDaemonUpstart		| installLog
  
  [ $dtype = 'U' ] && UpdateSELinuxPolicy install	| installLog
  
  cmdDaemon 'start'				| installLog
}

function UpdateSELinuxPolicy()
{
  local action="$1"
  local cmd
  cmdExists semodule || return
  
  if [ "$action" = install ]; then
    cmd="--$action=$TVD_SEL_POLICY"
  else
    cmd="--$action=$TVD_SEL_MODULE"
  fi
  
  echo "semodule $cmd"
  semodule "$cmd"
}

function installDaemonSysV()
{
  exec 2>&1

  installLogHeader "Installing daemon ($TV_VERSION) for 'SystemV' ..."
  installDaemonCfg "$TVD_SYSV_DIR" "$TVD_SYSV_SRC" "$TVD_SYSV_FILE"
  
  local chkcfg='chkconfig'
  cmdExists $chkcfg || chkcfg='/sbin/chkconfig'	# not in PATH on CentOS 5.x

  cmdExists $chkcfg     && $chkcfg --add "$TVD_SYSV_FILE"			&& return
  cmdExists update-rc.d && update-rc.d "$TVD_SYSV_FILE" defaults 99 5	&& return

  echo "Failed to update daemon configuration"
}

function installDaemonSystemD()
{
  exec 2>&1

  installLogHeader "Installing daemon ($TV_VERSION) for 'systemd' ..."
  installDaemonCfg "$TVD_SYSD_DIR" "$TVD_SYSD_FILE"
  systemctl daemon-reload		# just in case...

  echo "Try: systemctl enable $TVD_SYSD_FILE"
  systemctl enable "$TVD_SYSD_FILE"			# on Fedora 15, systemctl does not accept a full path (to /opt/...)
  [ $? = 0 ] && return
  
  echo "Try: systemctl enable $TV_SCRIPT_DIR/$TVD_SYSD_FILE"
  systemctl enable "$TV_SCRIPT_DIR/$TVD_SYSD_FILE"	# on openSUSE 12.2, systemctl does not accept a sole filename (if symlink?)
}

function installDaemonUpstart()
{
  exec 2>&1

  installLogHeader "Installing daemon ($TV_VERSION) for 'upstart' ..."
  
  installDaemonCfg "$TVD_UPST_DIR" "$TVD_UPST_SRC" "$TVD_UPST_FILE"
  initctl reload-configuration
}

function installDaemonCfg
{
  local dir="$1"
  local file="$2"
  local link="$3"
  [ -n "$link" ] || link="$file"

  [ -d "$dir" ] || return

  echo "installing $dir/$link ("$TV_SCRIPT_DIR/$file")"
  cp -f "$TV_SCRIPT_DIR/$file" "$dir/$link"
}

function removeDaemon()
{
  exec 2>&1
  
  removeDaemonAny			| installLog
  
  true
}

function removeDaemonAny()
{
  installLogHeader "Removing ..."
  cmdDaemon 'stop'
  stopTeamViewer	# just to make sure ...
 
 # TODO verify / update
 
  if [ -e "$TVD_SYSV_PATH" ]; then
    rm -f "$TVD_SYSV_PATH"
    cmdExists chkconfig   && chkconfig --del "$TVD_SYSV_FILE"
    cmdExists update-rc.d && update-rc.d "$TVD_SYSV_FILE" remove
  fi

  if [ -e "$TVD_UPST_PATH" ]; then
    rm -f "$TVD_UPST_PATH"
    local dtype='V'
    detectUpstart && dtype='U'
    [ $dtype = 'U' ] && initctl reload-configuration
    [ $dtype = 'U' ] && UpdateSELinuxPolicy remove
  fi

  if detectSystemD; then
    systemctl disable "$TVD_SYSD_FILE"
    local success=$?
    [ $success = 0 ] || echo try again, full path...
    [ $success = 0 ] || systemctl disable "$TV_SCRIPT_DIR/$TVD_SYSD_FILE"
    rm -f "$TVD_SYSD_PATH"
    systemctl daemon-reload
  fi
  
  true
}

function stopTeamViewer()
{
  teamviewer --kill # Kill all running TV instances, if any
}

function cmdDaemon()
{  
  local opt="$1"  
  local cmd="$(daemonCtl $opt)"
  
  echo "$cmd"
  eval "$cmd" && return

  echo "fail"
  false
}

function daemonCtl()
{  
  local opt="$1"  
  local cmd="$TVD_SYSV_PATH $opt"				# SystemV
  detectUpstart && cmd="initctl $opt teamviewerd"		# Upstart
  detectSystemD && cmd="systemctl $opt $TVD_SYSD_FILE"		# SystemD
  echo "$cmd"
}
