#!/bin/sh

#      Copyright (C) 2008-2017 Team XBMC
#      http://kodi.tv
#
#  This Program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2, or (at your option)
#  any later version.
#
#  This Program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with XBMC; see the file COPYING.  If not, write to
#  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#  http://www.gnu.org/copyleft/gpl.html

APP=Kodi
bin_name=kodi
SAVED_ARGS="$@"
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
LIBDIR="/usr/lib/arm-linux-gnueabihf"
APP_BINARY=$LIBDIR/${bin_name}/kodi-rbpi
CRASHLOG_DIR=${CRASHLOG_DIR:-$HOME}
KODI_DATA=${KODI_DATA:-"${HOME}/.${bin_name}"} # mapped to special://home/
WINDOWING=${WINDOWING:-"auto"}


# Black Screen on exit fix
ORIGINAL_DEPTH=`fbset | head -3 | tail -1 | cut -d " " -f 10`

# PiPplware fixes
if pgrep "fbi" > /dev/null		
then		
    sudo killall fbi >/dev/null 2>&1		
fi		
if pgrep "cec-client" > /dev/null		
then		
    sudo service cec stop >/dev/null 2>&1		
fi

# EmulationStation screen resolution fix
save_screen_mode() {
    local status="$(tvservice -s)"
    if echo "$status" | grep -qE "(PAL|NTSC)"; then
        MODE_TYPE=$(echo "$status" | grep -oE "(PAL|NTSC)")
        MODE_INFO=$(echo "$status" | grep -oE "([0-9]+\:[0-9]+)")
    else
        MODE_TYPE=$(echo "$status" | grep -oE "(CEA|DMT)")
        MODE_INFO=$(echo "$status" | grep -oE "\([0-9]+\)" | tr -d '()')
    fi
}

restore_screen_mode() {
    if [ "$MODE_TYPE" = "PAL" ] || [ "$MODE_TYPE" = "NTSC" ]; then
        tvservice -c "$MODE_TYPE $MODE_INFO" >/dev/null
    else
        tvservice -e "$MODE_TYPE $MODE_INFO" >/dev/null
    fi
    sleep 1
}

save_screen_mode

is_fkms() {
  if grep -q okay /proc/device-tree/soc/v3d@7ec00000/status 2> /dev/null || grep -q okay /proc/device-tree/soc/firmwarekms@7e600000/status 2> /dev/null ; then
    return 0
  else
    return 1
  fi
}

# pick correct version for armv6 or armv7
rev="$(sed -n '/^Revision/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo)"

if [ $(((0x$rev >> 23) & 1)) -ne 0 ] && [ $(((0x$rev >> 12) & 15)) -eq 3 ] || is_fkms; then
  postfix="_v8"
elif [ $(((0x$rev >> 23) & 1)) -ne 0 ] && [ $(((0x$rev >> 12) & 15)) -ne 0 ]; then
  postfix="_v7"
fi

# if RPI 4 and running X11 change VT
if [ "$postfix" = "_v8" ] && pgrep "X" > /dev/null; then
  vt=$(sudo /bin/fgconsole)
  sudo /bin/chvt 8
fi

# Workaround for high CPU load with nvidia GFX
export __GL_YIELD=USLEEP

# Fix wasting RAM due to fragmentation
export MALLOC_MMAP_THRESHOLD_=131072

# Check for some options used by this script
while [ "$#" -gt "0" ]
do
    case "$1" in
        --setlibdir)
            LIBDIR="$2"
            shift; shift
            ;;
        --windowing)
            WINDOWING="$2"
            echo "$SAVED_ARGS" | sed "s/--windowing[ ]*$2//g"
            shift; shift
            ;;
        *)
            shift
            ;;
    esac
done

# Note: by default only one of those binaries exists
# To be able to select a different one, if has to be compiled specifically
# Your distribution might provide extra packages for those
if [ "$WINDOWING" = "auto" ]; then
    # Wayland
    if [ -n "$WAYLAND_DISPLAY" ] && [ -x $LIBDIR/${bin_name}/${bin_name}-wayland ]; then
        KODI_BINARY=$LIBDIR/${bin_name}/${bin_name}-wayland
    # X11
    elif echo $DISPLAY | grep -qE ":[0-9]+" && [ -x $LIBDIR/${bin_name}/${bin_name}-x11 ]; then
        KODI_BINARY=$LIBDIR/${bin_name}/${bin_name}-x11
    # GBM/DRM
    elif [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && [ -x $LIBDIR/${bin_name}/${bin_name}-gbm ]; then
        KODI_BINARY=$LIBDIR/${bin_name}/${bin_name}-gbm
    # Default kodi.bin
    else
        KODI_BINARY=${APP_BINARY}
    fi
elif [ -n "$WINDOWING" ]; then
    KODI_BINARY=$LIBDIR/${bin_name}/${bin_name}-${WINDOWING}
else
    KODI_BINARY=${APP_BINARY}
fi

if [ ! -x ${KODI_BINARY}${postfix} ]; then
    echo "Error: ${KODI_BINARY}${postfix} not found"
    exit 2
fi

APPORT_CORE="/var/crash/$(echo -n ${KODI_BINARY}${postfix}|tr / _).$(id -u).crash"

migrate_home()
{
  [ "$(basename $0)" = "xbmc" ] && echo "WARNING: Running ${bin_name} as "xbmc" is deprecated and will be removed in later versions, please switch to using the ${bin_name} binary"

  #check if data migration is needed
  if [ -d "${HOME}/.xbmc" ] && [ ! -d "${KODI_DATA}" ]; then
      echo "INFO: migrating userdata folder. Renaming ${HOME}/.xbmc to $KODI_DATA"
      mv ${HOME}/.xbmc $KODI_DATA
      touch ${KODI_DATA}/.kodi_data_was_migrated
  fi
}

command_exists()
{
  command -pv $1 >/dev/null 2>&1
}

single_stacktrace()
{
  # core filename is either "core.$PID" or "core"
  find "$1" -maxdepth $2 -name 'core*' | while read core; do
      LC_ALL=C gdb --core="$core" --batch 2> /dev/null | grep -q "^Core was generated by \`${KODI_BINARY}${postfix}" || continue
      echo "=====>  Core file: "$core" ($(stat -c%y "$core"))" >> $FILE
      echo "        =========================================" >> $FILE
      gdb "${KODI_BINARY}${postfix}" --core="$core" --batch -ex "thread apply all bt" 2> /dev/null >> $FILE
      rm -f "$core"
  done
}

print_crash_report()
{
  FILE="$CRASHLOG_DIR/${bin_name}_crashlog-`date +%Y%m%d_%H%M%S`.log"
  echo "############## $APP CRASH LOG ###############" >> $FILE
  echo >> $FILE
  echo "################ SYSTEM INFO ################" >> $FILE
  printf " Date: " >> $FILE
  date >> $FILE
  echo " $APP Options: $*" >> $FILE
  printf " Arch: " >> $FILE
  uname -m >> $FILE
  printf " Kernel: " >> $FILE
  uname -rvs >> $FILE
  printf " Release: " >> $FILE
  if [ -f /etc/os-release ]; then
	  . /etc/os-release
	  echo $NAME $VERSION >> $FILE
  elif command_exists lsb_release; then
    echo >> $FILE
    lsb_release -a 2> /dev/null | sed -e 's/^/    /' >> $FILE
  else
    echo "lsb_release not available" >> $FILE
  fi
  echo "############## END SYSTEM INFO ##############" >> $FILE
  echo >> $FILE
  echo "############### STACK TRACE #################" >> $FILE
  if command_exists gdb; then
    if command_exists systemd-coredumpctl; then
      systemd-coredumpctl dump -o core $(basename ${KODI_BINARY}${postfix}) > /dev/null 2>&1
    elif command_exists coredumpctl; then
      coredumpctl dump -o core $(basename ${KODI_BINARY}${postfix})  > /dev/null 2>&1
    elif command_exists apport-unpack && test -f "${APPORT_CORE}"; then
      TMP_DIR="$(mktemp -d -p ${HOME})"
      if [ -d "${TMP_DIR}" ]; then
        rm -f "${HOME}/core"
        apport-unpack "${APPORT_CORE}" "${TMP_DIR}"
        mv "${TMP_DIR}/CoreDump" "${HOME}/core"
        rm -rf "${TMP_DIR}"
      fi
    fi
    single_stacktrace "$PWD" 1
    # Find in plugins directories
    if [ $KODI_HOME ]; then
      BASEDIR=$KODI_HOME
    else
      BASEDIR="$LIBDIR/${bin_name}/"
    fi
    single_stacktrace "$BASEDIR" 5
    # find in userdata dir
    single_stacktrace "$HOME" 5
    # try /proc/sys/kernel/core_pattern
    # Check if it does not contain a pipe to a program (see man 5 core)
    if [ "$(cat /proc/sys/kernel/core_pattern | cut -c 1)" != "|" ]; then
      [ -d "$(dirname $(cat /proc/sys/kernel/core_pattern))" ] && single_stacktrace "$(dirname $(cat /proc/sys/kernel/core_pattern))" 1
    fi
  else
    echo "gdb not installed, can't get stack trace." >> $FILE
  fi
  echo "############# END STACK TRACE ###############" >> $FILE
  echo >> $FILE
  echo "################# LOG FILE ##################" >> $FILE
  echo >> $FILE
  if [ -f $KODI_DATA/temp/kodi.log ]
  then
    cat $KODI_DATA/temp/kodi.log >> $FILE
    echo >> $FILE
  else
    echo "Logfile not found in the usual place." >> $FILE
    echo "Please attach it separately." >> $FILE
    echo "Use pastebin.com or similar for forums or IRC." >> $FILE
  fi
  echo >> $FILE
  echo "############### END LOG FILE ################" >> $FILE
  echo >> $FILE
  echo "############ END $APP CRASH LOG #############" >> $FILE
  echo "Crash report available at $FILE"
}

migrate_home

if command_exists gdb; then
  # Output warning in case ulimit is unsupported by shell
  eval ulimit -c unlimited
  if [ ! $? = "0" ]; then
    echo "${bin_name}: ulimit is unsupported by this shell" 1>&2
  fi
fi

LOOP=1
while [ $(( $LOOP )) = "1" ]
do
  [ -f "${APPORT_CORE}" ] && rm -f "${APPORT_CORE}"
  LOOP=0
  ${KODI_BINARY}${postfix} --lircdev /var/run/lirc/lircd $SAVED_ARGS
  RET=$?
  if [ $(( $RET == 65 )) = "1" ]
  then # User requested to restart app
    LOOP=1
  elif [ $(( ($RET >= 131 && $RET <= 136) || $RET == 139 )) = "1" ]
  then # Crashed with core dump
    print_crash_report
  fi
done

# Raspberry Pi fixes

restore_screen_mode
fbset -depth 8 > /dev/null 2>&1
fbset -depth $ORIGINAL_DEPTH > /dev/null 2>&1
if pgrep "X" > /dev/null
then
    xrefresh >/dev/null 2>&1
fi
if [ -f "/usr/bin/cec-daemon" ]
then
    sudo service cec start >/dev/null 2>&1
fi

# if RPI 4 and running X11 change VT
if [ "$postfix" = "_v8" ] && pgrep "X" > /dev/null; then
  sudo /bin/chvt $vt
fi

exit $RET
