#!/bin/bash
# TODO:
# 1. Check for ANDROID_SERIAL/multiple devices

if [ -z "$ANDROID_BUILD_TOP" ]; then
  >&2 echo '$ANDROID_BUILD_TOP is not set. Source build/envsetup.sh.'
  exit 1
fi

# We can use environment variables (like ANDROID_BUILD_TOP) from the user's
# shell, but not functions (like gettop), so we need to source envsetup in here
# as well.
source $ANDROID_BUILD_TOP/build/envsetup.sh
echo

function adb_get_product_device() {
  local candidate=`adb shell getprop ro.hardware | tr -d '\r\n'`
  if [[ "$candidate" =~ ^(goldfish|ranchu)$ ]]; then
    # Emulator builds use product.device for OUT folder
    candidate=`adb shell getprop ro.product.device | tr -d '\r\n'`
  fi
  echo $candidate
}

# returns 0 when process is not traced
function adb_get_traced_by() {
  echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:\t//" | tr -d '\r\n'`
}

function get_symbols_directory()
{
    echo $(get_abs_build_var TARGET_OUT_UNSTRIPPED)
}

function gdbwrapper()
{
    local GDB_CMD="$1"
    shift 1
    $GDB_CMD -x "$@"
}

function gdbclient() {
  local PROCESS_NAME="n/a"
  local PID=$1
  local PORT=5039
  if [ -z "$PID" ]; then
    echo "Usage: gdbclient <pid|processname> [port number]"
    return -1
  fi
  local DEVICE=$(adb_get_product_device)

  local ROOT=$(gettop)
  if [ -z "$ROOT" ]; then
    # This is for the situation with downloaded symbols (from the build server)
    # we check if they are available.
    ROOT=`realpath .`
  fi


  if [[ -z "$DEVICE" || ! -d "$ROOT/out/target/product/$DEVICE" ]]; then
    if [ -z "$BLISS_BUILD" ]; then
      echo "Error: Unable to get device name. Please check if device is connected and ANDROID_SERIAL is set."
      return -2
    fi
    DEVICE=$BLISS_BUILD
  fi

  if [ -n "$2" ]; then
    PORT=$2
  fi

  local SYS_OUT_ROOT=$(get_build_var OUT_DIR)
  local OUT_ROOT="${SYS_OUT_ROOT:-${OUT_DIR:-$ROOT/out}}/target/product/$DEVICE"
  local SYMBOLS_DIR="$OUT_ROOT/symbols"
  local IS_TAPAS_USER="$(get_build_var TARGET_BUILD_APPS)"
  local TAPAS_SYMBOLS_DIR=

  if [ $IS_TAPAS_USER ]; then
    TAPAS_SYMBOLS_DIR=$(get_symbols_directory)
  fi

  if [ ! -d $SYMBOLS_DIR ]; then
    if [ $IS_TAPAS_USER ]; then
      mkdir -p $SYMBOLS_DIR/system/bin
    else
      echo "Error: couldn't find symbols: $SYMBOLS_DIR does not exist or is not a directory."
      return -3
    fi
  fi

  # let's figure out which executable we are about to debug
  # check if user specified a name -> resolve to pid
  if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then
    PROCESS_NAME=$PID
    PIDS=( $(adb shell "pidof $PROCESS_NAME 2> /dev/null" | tr -d '\r\n') )
    if [[ ${#PIDS[@]} == 0 ]]; then
      echo "Error: couldn't resolve pid by process name: $PROCESS_NAME"
      return -4
    elif [[ ${#PIDS[@]} != 1 ]]; then
      echo "Error: more than one 1 PID resolved by process name: $PROCESS_NAME"
      echo "       PIDs -> ${PIDS[@]}"
      return -5
    fi
    PID="${PIDS[0]}"
    echo "Resolved pid for $PROCESS_NAME is [$PID]"
  fi

  local ID=`adb shell id -u`
  if [ "$ID" != "0" ]; then
    echo "Error: gdbclient only works if you've run 'adb root'"
    return -4
  fi

  local EXE=`adb shell readlink /proc/$PID/exe | tr -d '\r\n'`
  if [ -z "$EXE" ]; then
    echo "Error: couldn't find executable for pid $PID --- is the process still alive?"
    return -4
  fi

  local LOCAL_EXE_PATH=$SYMBOLS_DIR$EXE

  if [ ! -f $LOCAL_EXE_PATH ]; then
    if [ $IS_TAPAS_USER ]; then
      adb pull $EXE $LOCAL_EXE_PATH
    else
      echo "Error: unable to find symbols for executable $EXE: file $LOCAL_EXE_PATH does not exist"
      return -5
    fi
  fi

  local USE64BIT=""

  if [[ "$(file $LOCAL_EXE_PATH)" =~ 64-bit ]]; then
    USE64BIT="64"
  fi

  # and now linker for tapas users...
  if [ -n "$IS_TAPAS_USER" -a ! -f "$SYMBOLS_DIR/system/bin/linker$USE64BIT" ]; then
    adb pull /system/bin/linker$USE64BIT $SYMBOLS_DIR/system/bin/linker$USE64BIT
  fi

  local GDB
  case $(uname -s) in
    Darwin)
      GDB=$ANDROID_BUILD_TOP/prebuilts/gdb/darwin-x86/bin/gdb
      ;;

    Linux)
      GDB=$ANDROID_BUILD_TOP/prebuilts/gdb/linux-x86/bin/gdb
      ;;

    *)
      echo "Error: Unknown platform '$(uname -s)'"
      return 1
      ;;
  esac

  local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | tr -d '\r\n'`

  # TODO: check if tracing process is gdbserver and not some random strace...
  if [ "$(adb_get_traced_by $PID)" -eq 0 ]; then
    # start gdbserver
    echo "Starting gdbserver..."
    # TODO: check if adb is already listening $PORT
    # to avoid unnecessary calls
    echo ". adb forward for port=$PORT..."
    adb forward tcp:$PORT tcp:$PORT
    echo ". starting gdbserver to attach to pid=$PID..."
    adb shell gdbserver$USE64BIT :$PORT --attach $PID &
    echo ". give it couple of seconds to start..."
    sleep 2
    echo ". done"
  else
    echo "It looks like gdbserver is already attached to $PID (process is traced), trying to connect to it using local port=$PORT"
    adb forward tcp:$PORT tcp:$PORT
  fi

  local OUT_SO_SYMBOLS=$SYMBOLS_DIR/system/lib$USE64BIT
  local TAPAS_OUT_SO_SYMBOLS=$TAPAS_SYMBOLS_DIR/system/lib$USE64BIT
  local OUT_VENDOR_SO_SYMBOLS=$SYMBOLS_DIR/vendor/lib$USE64BIT
  local ART_CMD=""

  local SOLIB_SYSROOT=$SYMBOLS_DIR
  local SOLIB_SEARCHPATH=$OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx:$OUT_VENDOR_SO_SYMBOLS:$OUT_VENDOR_SO_SYMBOLS/hw:$OUT_VENDOR_SO_SYMBOLS/egl

  if [ $IS_TAPAS_USER ]; then
    SOLIB_SYSROOT=$TAPAS_SYMBOLS_DIR:$SOLIB_SYSROOT
    SOLIB_SEARCHPATH=$TAPAS_OUT_SO_SYMBOLS:$SOLIB_SEARCHPATH
  fi

  echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $SOLIB_SYSROOT"
  echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $SOLIB_SEARCHPATH"
  local DALVIK_GDB_SCRIPT=$ROOT/development/scripts/gdb/dalvik.gdb
  if [ -f $DALVIK_GDB_SCRIPT ]; then
    echo >>"$OUT_ROOT/gdbclient.cmds" "source $DALVIK_GDB_SCRIPT"
    ART_CMD="art-on"
  else
    echo "Warning: couldn't find $DALVIK_GDB_SCRIPT - ART debugging options will not be available"
  fi
  echo >>"$OUT_ROOT/gdbclient.cmds" "target remote :$PORT"
  if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then
    echo >> "$OUT_ROOT/gdbclient.cmds" $ART_CMD
  fi

  echo >>"$OUT_ROOT/gdbclient.cmds" ""

  gdbwrapper $GDB "$OUT_ROOT/gdbclient.cmds" "$LOCAL_EXE_PATH"
}

gdbclient $*
