

declare -gr TV_LD_X86_64_PATH='/lib64/ld-linux-x86-64.so.2'
declare -gr TV_LD_X86_32_PATH='/lib/ld-linux.so.2'
declare -gr TV_LD_ARM_HF_PATH='/lib/ld-linux-armhf.so.3'


function fail()
{
  echo -e "\nError: $@\n"
  false
}

function die()
{
  echo -e "\nError: $@\n"
  exit 1
}

function Rdie()
{
  Recho "\nError: $@\n"
  exit 1
}

function Rdie2()
{
  Recho "\n $@ \n" 1>&2
  exit 1
}

function ABecho()
{
  printf "\E[1m %-35s \E[0m %s \n" "$1" "$2"
}

function HeadEcho()
{
  printf "%-18s %s\n" "$1" "$2"
}

function IndentEcho()
{
  local data="$1"
  local pre="$2"

  while read -r line; do
    echo "$pre$line"
  done <<< "$data"
}

function BDecho()
{
  echo -ne "\E[1m$@\E[0m\n"
}

function Recho()
{
  # force black background: "\E[1;31;40m$@\E[0m\n"
  echo -ne "\E[1;31m$@\E[0m\n"
}

function Gecho()
{
  # force black background: "\E[1;32;40m$@\E[0m\n"
  echo -ne "\E[1;32m$@\E[0m\n"
}

function Yecho()
{
  # force black background: "\E[1;33;40m$@\E[0m\n"
  #        auto background: "\E[1;33m$@\E[0m\n"
  echo -ne "\E[1;33;40m$@\E[0m\n"
}

function Techo()
{
  echo "$@" | tee --append "$TV_STARTLOG"
}

function TeeLog()
{
  local append=$( [ "$1" = 'reset' ] || echo '--append' )
  tee $append "$TV_STARTLOG"
}

function Log()
{
  cat >> "$TV_STARTLOG"
}

function ShowGUIWarningMessageBox()
{
  local -r msg="$1"
  local -r title="${2:-TeamViewer}"

  if cmdExists kdialog; then
    kdialog --title "$title" --sorry "$msg"
  elif cmdExists zenity; then
    zenity --warning --width=400 --title="$title" --text="$msg" &> /dev/null
  elif cmdExists yad; then
    yad --image dialog-warning --button=gtk-ok --borders 10 --width 400 --center --title "$title" --text "$msg"
  elif cmdExists xmessage; then
    echo -e "$msg" | xmessage -center -title "$title" -file -
  fi
}


function cmdExists()
{
  command -v "$1" >/dev/null 2>&1
}

function isStrAscii()
{
  local str="$1"

  # echo -n "$str" | od -x -w2 | cut -d' ' -f2 | grep -E '^[89abcdef]|^..[89abcdef]' # also works
  for (( i=0; i<${#str}; i++ )); do
    (( $(printf '%d' \'${str:$i:1}) > 127 )) && return 1
  done

  return 0
}

function isStrNumeric()
{
  local str="$1"

  [ "$str" -eq "$str" ] 2>/dev/null
}

function getInitCmd()
{
  #exec 2> /dev/null
  readlink /proc/1/exe 2> /dev/null
  #cat /proc/1/cmdline | tr "\000" " " | cut -d' ' -f1
}


function assertVariableSet()
{
  declare -p &>/dev/null $1 || die "variable not set: $1"
}

function expectVariables()
{
  while (( $# > 0 )); do
    assertVariableSet $1
    shift
  done
}

function make_path()
{
  local path="$1"
  local mode=${2:+-m $2}    # e.g. '-m 755' or ''
  if [ -d "$path" ] ; then
      # Don't fail here, as chmod is not possible on all file systems
      [ -n "$2" ] && chmod $2 "$path"
      true
  else
      mkdir -p $mode "$path" || fail "Could not create $path"
  fi
}

function validateUser()
{
  if [ -n "$SUDO_UID" ] && [ "$SUDO_UID" != "$UID" ]; then
    Techo -e " *** TeamViewer can not be executed with sudo! ***\n Either use your normal user account without sudo\n or use a the real root account to log in to your desktop\n and start TeamViewer with '--allowRoot' (not recommended!).\n"

    chown $SUDO_UID:$SUDO_GID "$TV_STARTLOG"

    return 1
  fi
}

function isSuperUser # root or sudo
{
  local userid=$(id -u)
  [ "$userid" == 0 ]
}

function rootSuggest()
{
  isSuperUser || echo -e "\nTry with root / sudo ?"
  false
}

function isInstalledTV()
{
  [ "$TV_PKGTYPE" == 'DEB'    ] && return 0
  [ "$TV_PKGTYPE" == 'RPM'    ] && return 0
  [ "$TV_PKGTYPE" == 'TAR_IN' ] && return 0
  [ "$TV_PKGTYPE" == 'TAR_NI' ] && return 1
  [ "$TV_PKGTYPE" == 'TAR_QS' ] && return 1

  die 'Invalid package type'
}

function isTarPackage()
{
  [ "$TV_PKGTYPE" == 'TAR_IN' ] && return 0
  [ "$TV_PKGTYPE" == 'TAR_NI' ] && return 0
}

function installedTVorDie()
{
  isInstalledTV || die 'Only available if TeamViewer is installed'
}

function isQuickSupport()
{
  [ "$TV_EDITION" == 'QS' ]
}

function isHost()
{
  [ "$TV_EDITION" == 'HOST' ]
}

function hasArmhfSupport()
{
  [ -x "$TV_LD_ARM_HF_PATH" ]
}

function hasX86_32Support()
{
  [ -x "$TV_LD_X86_32_PATH" ]
}

function hasX86_64Support()
{
  [ -x "$TV_LD_X86_64_PATH" ]
}

function checkSupportedArchitecture()
{
  { hasX86_64Support || hasX86_32Support || hasArmhfSupport; } && return

  Rdie "Unsupported architecture:\n\tCould not find $TV_LD_X86_32_PATH\n\tCould not find $TV_LD_X86_64_PATH\n\tCould not find $TV_LD_ARM_HF_PATH"
}

function getSystemArchitecture()
{
  hasX86_64Support && { echo x86_64 ; return; }
  hasX86_32Support && { echo x86_32 ; return; }
  hasArmhfSupport  && { echo armhf  ; return; }
}

function getFileArchitecture()
{
  local -r file="$1"
  local -r info="$(file "$file" 2> /dev/null)"

  local -r ldi64="$(basename "$TV_LD_X86_64_PATH")"
  local -r ldi32="$(basename "$TV_LD_X86_32_PATH")"
  local -r ldarm="$(basename "$TV_LD_ARM_HF_PATH")"

  [[ "$info" = *"$ldi64"* ]] && { echo x86_64 ; return; }
  [[ "$info" = *x86-64*   ]] && { echo x86_64 ; return; }
  [[ "$info" = *"$ldi32"* ]] && { echo x86_32 ; return; }
  [[ "$info" = *'Intel 80386'* ]] && { echo x86_32 ; return; }
  [[ "$info" = *"$ldarm"* ]] && { echo armhf  ; return; }
}

function updateMenuEntries()
{
  local -r action="$1"    # install / uninstall
  local -r dtfile="${TV_DESKTOP_FILE##*/}"

  #always remove - equal strings: cf. triggerpostun
  xdg-desktop-menu uninstall --mode system "$TV_DESKTOP_FILE"
  [ "$TV_DESKTOP_FILE" != "$dtfile" ] && \
    xdg-desktop-menu uninstall --mode system "$dtfile"

  # prefer installed xdg script (tvw_config)
  # use novendor to allow the new naming scheme (org.name.product)
  [ "$action" = 'install' ] && \
    xdg-desktop-menu install --novendor --mode system "$TV_DESKTOP_FILE"

  cmdExists update-menus            && update-menus
  cmdExists update-desktop-database && update-desktop-database
  cmdExists update-icon-caches      && update-icon-caches /usr/share/icons/hicolor
}
