#!/bin/bash

# command line parameters that are not essential for normal TeamViewer usage

function PrintHelp()
{
  PrintVersion
  echo
  ABecho "teamviewer"		"start TeamViewer user interface (if not running)"
  echo
  ABecho "teamviewer --help"			"print this help screen"
  ABecho "teamviewer --version"			"print version information"
  ABecho "teamviewer --info"			"print version, status, id"
  ABecho "teamviewer --ziplog"			"create a zip containing all teamviewer logs (useful when contacting support)"
  echo
  isInstalledTV || return
  ABecho "teamviewer --passwd [PASSWD]"	"set a password (useful when installing remote (ssh)"
  echo
  ABecho "teamviewer --daemon status"	"show current status of the TeamViewer daemon"
  ABecho "teamviewer --daemon start"	"start		TeamViewer daemon"
  ABecho "teamviewer --daemon stop"		"stop		TeamViewer daemon"
  ABecho "teamviewer --daemon restart"	"stop/start	TeamViewer daemon"
  ABecho "teamviewer --daemon disable"	"disable	TeamViewer daemon - don't start daemon on system startup"
  ABecho "teamviewer --daemon enable"	"enable		TeamViewer daemon - start daemon on system startup (default)"
  echo
}

function PrintVersion()
{
  ABecho "TeamViewer" "$TV_VERSION"
}

function PrintInfo()
{
  PrintVersion
  echo
  PrintDaemonStatus
  echo
  PrintTeamViewerID
}

function PrintDaemonStatus()
{
  local cmd="$(daemonCtl 'status')"
  local txt="n/a"

  if [ isInstalledTV ] ; then
    txt="$(eval "$cmd")"
    [ $? = 0 ] || txt='n/a (error)'
  fi
  
  ABecho "teamviewerd status" "$txt"
}

function PrintTeamViewerID()
{
  local config="$TV_BASE_DIR/config/global.conf"
  local txt='not found'
  local tvid
  
  [ -e "$config" ] && tvid=$( grep 'ClientID' "$config" | cut --delimiter='=' -f2 )
  [ -n "$tvid"   ] && txt="$tvid"

  ABecho "TeamViewer ID:" "$tvid"

  if [ -z "$tvid" ] && isInstalledTV; then
    echo "Try restarting the TeamViewer daemon (e.g. teamviewer --daemon restart)"
  fi
}

function SetPasswd()
{
  local pwd="$1"
  [ -n "$pwd" ] || die 'no password specified'

  installedTVorDie
  isSuperUser || die 'You need root permissions for this operation'

  Run_Daemon 'stop' > /dev/null
  
  "$TV_BIN_DIR/teamviewerd" --passwd "$pwd"
  case $? in
    0  ) echo 'ok'	;;
    11 ) echo 'password too short - use at least 8 characters [E11]'	;;
    12 ) echo 'password too long  - use 12 or less characters [E12]'	;;
    13 ) echo 'password not accepted - illegal char detected [E13]'	;;
    14 ) echo 'passwort invalid - validation failed [E14]'	;;
    *  ) echo 'unknown response'	;;
   esac
  
  Run_Daemon 'start' > /dev/null || die 'failed to restart the daemon'
  echo
}

function ExportLicense()
{
  local license="$1"
  local path='/tmp/tv_global.conf'

  [ -n "$license" ] || die 'no license specified'

  isSuperUser || die 'You need root permissions for this operation'

  Run_Daemon 'stop' > /dev/null
  
  "$TV_BIN_DIR/teamviewerd" --export-license "$license" "$path"
  case $? in
    0  ) echo "ok - license exported to '$path'"		;;
    11 ) echo "destination '$path' not accessible"		;;
    *  ) echo 'unknown response'	;;
   esac
  
  Run_Daemon 'start' > /dev/null || die 'failed to restart the daemon'
  echo
}

function StripPersonalInformation()
{
  local config
  local config_dir="$1"
  local strip_global=(
    '[bin  ] Certificate'
    '[bin  ] CertificateKey'
    '[bin  ] MultiPwdMgmtPwdData'
    '[bin  ] PermanentPassword'
    '[bin  ] PK'
    '[bin  ] SK'
    '[bin  ] SRPPasswordMachineIdentifier'
    )
  local strip_client=(
    '[bin  ] BuddyLoginTokenAES'
    '[bin  ] BuddyLoginTokenSecretAES'
    )

  ( # subshell: preserve pwd
    cd "$config_dir"

    # global.conf
    config='global.conf'
    for s in "${strip_global[@]}"; do
      StripItem "$config" "$s"
    done
  
    # client.conf
    for config in *'/client.conf' ; do
      [ -e "$config" ] || continue
      for s in "${strip_client[@]}"; do
        StripItem "$config" "$s"
      done
    done
  )
}

function StripItem()
{
  local file="$1"
  local pattern="$2 ="
  local sedpattern="${pattern/[/\\[}"
        sedpattern="${sedpattern/]/\\]}"

  grep -q "$sedpattern" "$file" || return

  sed -i -e "/$sedpattern/d" "$file"
  echo "# $pattern (stripped)" >> "$file"
}

function CollectALSAInformation()
{
  local alsa="$1"/alsa

  function ALSAInformationHeader()
  {
    echo -e "\n" >> $alsa
    echo $1 >> $alsa
    echo "======================================" >> $alsa
    echo >> $alsa
  }

  echo "ALSA system information" > $alsa
  echo "++++++++++++++++++++++++++++++++++++++" >> $alsa

  if cmdExists alsa-info ; then

    alsa-info --output $alsa --no-upload > /dev/null

  else

    ALSAInformationHeader "ALSA dmesg"
    dmesg | grep -i alsa >> $alsa

    ALSAInformationHeader "Sound Devices"
    find /dev/snd | sort >> $alsa

    if cmdExists aplay ; then
      ALSAInformationHeader "Playback information"
      echo -e "Devices:" >> $alsa
      aplay -l >> $alsa
      echo -e "\n\nStreams:\n" >> $alsa
      aplay -L >> $alsa
    fi

    if cmdExists arecord ; then
      ALSAInformationHeader "Capture information"
      echo -e "Devices:" >> $alsa
      arecord -l >> $alsa
      echo -e "\n\nStreams:\n" >> $alsa
      arecord -L >> $alsa
    fi

    if cmdExists amixer ; then
      ALSAInformationHeader "Mixer information"
      for control in /dev/snd/controlC* ; do
        card=${control#/dev/snd/controlC}
        echo -e "\nhw:$card:\n======" >> $alsa
        amixer -c $card scontents >> $alsa
      done
    fi

  fi
}

function CollectSystemInformation()
{
  local sysinfo_dir="$1"
  local logs=(/var/log/X*.log* /proc/cpuinfo /proc/sys/kernel/shmmax)

  mkdir "$sysinfo_dir" || die "failed to create $sysinfo_dir"

  ( # subshell: preserve pwd
    cd "$sysinfo_dir"

    PATH=$PATH:/sbin:/usr/sbin

    # network interfaces
    cmdExists ifconfig && ifconfig -a > 'ifconfig'

    # uname -a
    cmdExists uname && uname -a > 'uname'

    # dbus names
    cmdExists dbus-send && dbus-send --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames > 'dbus-send' 2>&1

    # PCI
    cmdExists lspci && lspci > 'lspci'

    # USB
    cmdExists lsusb && lsusb > 'lsusb'

    # Kernel modules
    cmdExists lsmod && lsmod > 'lsmod'

    # ALSA info
    CollectALSAInformation "$sysinfo_dir"

    # copy X logs, some proc info
    for file in "${logs[@]}" ; do
      [ -f "$file" ] && cp "$file" .
    done
  )
}

function CreateZipLogTmpDir()
{
#  local ziplog_dir="/tmp/tv_ziplog_${RANDOM}_$(date +%M%S%N)"
#  while [ -d "$ziplog_dir" ]; do ziplog_dir="$ziplog_dir"A; done	# use unique name 
#  mkdir $ziplog_dir || die "Error creating folder '$ziplog_dir' in /tmp"
#  echo "$ziplog_dir"
  mktemp -d -p /tmp tv_ziplog_XXXXXX || die "Error creating temporary dir in /tmp"
}

function CreateZipLog()
{
  local ziplog_dir="$(CreateZipLogTmpDir)"
  local cfg_dir="config"
  local log_dir="logfiles"
  local sysinfo_dir="sysinfo"
  local archive="/tmp/tvlog_$(hostname)_$(date +%F)"
 
  echo "Creating a zip archive from all files in $log_dir and $cfg_dir"

  cp -Lr "$TV_BASE_DIR/$cfg_dir" $ziplog_dir
  cp -Lr "$TV_BASE_DIR/$log_dir" $ziplog_dir

  StripPersonalInformation "$ziplog_dir/$cfg_dir"

  CollectSystemInformation "$ziplog_dir/$sysinfo_dir"

  ( # subshell: preserve pwd
    cd "${ziplog_dir}"

    if cmdExists zip; then
      archive="$archive.zip"
      rm -f $archive
      zip -r9 $archive "$cfg_dir" "$log_dir" "$sysinfo_dir" || die "Done. An error ($?) occurred when creating archive $archive"
    else
      archive="$archive.tar.gz"
      rm -f $archive
      tar -zchf $archive "$cfg_dir" "$log_dir" "$sysinfo_dir" || die "Done. An error ($?) occurred when creating archive $archive"
    fi

    rm -fR $ziplog_dir		# delete temporary data
    chmod 666 $archive		# allow every user to read and delete

    Gecho "\n** Success**\n"
    echo "Archive written to $archive"
    echo
  ) || return

  isInstalledTV && (isSuperUser || Yecho "Warning: Ziplog should be executed as root or some important information may be missing")
}

