#!/bin/sh
#
# This is a wrapper script (based on kodi/xbmc script) to monitor subsurface and get debug information using GDB when a crash happens.
# Informations are stored in *.log file in CRASHLOG_DIR ($HOME by default)

APP=Subsurface
bin_name=subsurface
SAVED_ARGS="$@"
prefix="/usr"
CRASHLOG_DIR=${CRASHLOG_DIR:-$HOME}
APP_VERSION=$(${prefix}/bin/${bin_name} --version)

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 \`${prefix}/bin/${bin_name}" || continue
      echo "=====>  Core file: "$core" ($(stat -c%y "$core"))" >> $FILE
      echo "        =========================================" >> $FILE
      gdb "${prefix}/bin/${bin_name}" --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
  echo -n " Date: " >> $FILE
  LC_ALL=C date >> $FILE
  echo " $APP Options: $SAVED_ARGS" >> $FILE
  echo " $APP version: $APP_VERSION" >> $FILE
  echo -n " Arch: " >> $FILE
  uname -m >> $FILE
  echo -n " Kernel: " >> $FILE
  uname -rvs >> $FILE
  echo -n " 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 coredumpctl; then
      # Generate core
      core=$(mktemp -p /tmp/ core.subsurface.XXXXXXXXXX)
      coredumpctl dump ${prefix}/bin/${bin_name} > $core
      single_stacktrace "/tmp/" 1
    else
      # Find in current directory
      single_stacktrace "$PWD" 1
    fi
    # 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
    [ -d "$(dirname $(cat /proc/sys/kernel/core_pattern))" ] && single_stacktrace "$(dirname $(cat /proc/sys/kernel/core_pattern))" 1
  else
    echo "gdb not installed, can't get stack trace." >> $FILE
  fi
  echo "############# END STACK TRACE ###############" >> $FILE
  echo >> $FILE
  echo "############ END $APP CRASH LOG #############" >> $FILE
  echo "Crash report available at $FILE"
}

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
  LOOP=0
  "${prefix}/bin/${bin_name}" $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
#   echo "RET = $RET"
done

exit $RET
