#!/bin/sh
#
# Run the code in test.jar on the device. The jar should contain a top-level
# class named Main to run.

msg() {
    if [ "$QUIET" = "n" ]; then
        echo "$@"
    fi
}

RELOCATE="y"
GDB="n"
DEBUGGER="n"
INTERPRETER="n"
VERIFY="y"
OPTIMIZE="y"
ZYGOTE=""
QUIET="n"
DEV_MODE="n"
INVOKE_WITH=""
FLAGS=""
TARGET_SUFFIX="32"
GDB_TARGET_SUFFIX=""
SECONDARY_DEX=""
DEX_VERIFY=""

while true; do
    if [ "x$1" = "x--quiet" ]; then
        QUIET="y"
        shift
    elif [ "x$1" = "x--lib" ]; then
        shift
        if [ "x$1" = "x" ]; then
            echo "$0 missing argument to --lib" 1>&2
            exit 1
        fi
        LIB="$1"
        shift
    elif [ "x$1" = "x-Xcompiler-option" ]; then
        shift
        option="$1"
        FLAGS="${FLAGS} -Xcompiler-option $option"
        shift
    elif [ "x$1" = "x--runtime-option" ]; then
        shift
        option="$1"
        FLAGS="${FLAGS} $option"
        shift
    elif [ "x$1" = "x--boot" ]; then
        shift
        BOOT_OPT="$1"
        shift
    elif [ "x$1" = "x--debug" ]; then
        DEBUGGER="y"
        shift
    elif [ "x$1" = "x--gdb" ]; then
        GDB="y"
        DEV_MODE="y"
        shift
    elif [ "x$1" = "x--zygote" ]; then
        ZYGOTE="--zygote"
        msg "Spawning from zygote"
        shift
    elif [ "x$1" = "x--dev" ]; then
        DEV_MODE="y"
        shift
    elif [ "x$1" = "x--relocate" ]; then
        RELOCATE="y"
        shift
    elif [ "x$1" = "x--no-relocate" ]; then
        RELOCATE="n"
        shift
    elif [ "x$1" = "x--interpreter" ]; then
        INTERPRETER="y"
        shift
    elif [ "x$1" = "x--invoke-with" ]; then
        shift
        if [ "x$1" = "x" ]; then
            echo "$0 missing argument to --invoke-with" 1>&2
            exit 1
        fi
        if [ "x$INVOKE_WITH" = "x" ]; then
            INVOKE_WITH="$1"
        else
            INVOKE_WITH="$INVOKE_WITH $1"
        fi
        shift
    elif [ "x$1" = "x--no-verify" ]; then
        VERIFY="n"
        shift
    elif [ "x$1" = "x--no-optimize" ]; then
        OPTIMIZE="n"
        shift
    elif [ "x$1" = "x--" ]; then
        shift
        break
    elif [ "x$1" = "x--64" ]; then
        TARGET_SUFFIX="64"
        GDB_TARGET_SUFFIX="64"
        shift
    elif [ "x$1" = "x--secondary" ]; then
        SECONDARY_DEX=":$DEX_LOCATION/$TEST_NAME-ex.jar"
        shift
    elif expr "x$1" : "x--" >/dev/null 2>&1; then
        echo "unknown $0 option: $1" 1>&2
        exit 1
    else
        break
    fi
done

if [ "$ZYGOTE" = "" ]; then
    if [ "$OPTIMIZE" = "y" ]; then
        if [ "$VERIFY" = "y" ]; then
            DEX_OPTIMIZE="-Xdexopt:verified"
        else
            DEX_OPTIMIZE="-Xdexopt:all"
        fi
        msg "Performing optimizations"
    else
        DEX_OPTIMIZE="-Xdexopt:none"
        msg "Skipping optimizations"
    fi

    if [ "$VERIFY" = "y" ]; then
        msg "Performing verification"
    else
        DEX_VERIFY="-Xverify:none"
        msg "Skipping verification"
    fi
fi

msg "------------------------------"

if [ "$QUIET" = "n" ]; then
  adb shell rm -r $DEX_LOCATION
  adb shell mkdir -p $DEX_LOCATION
  adb push $TEST_NAME.jar $DEX_LOCATION
  adb push $TEST_NAME-ex.jar $DEX_LOCATION
else
  adb shell rm -r $DEX_LOCATION >/dev/null 2>&1
  adb shell mkdir -p $DEX_LOCATION >/dev/null 2>&1
  adb push $TEST_NAME.jar $DEX_LOCATION >/dev/null 2>&1
  adb push $TEST_NAME-ex.jar $DEX_LOCATION >/dev/null 2>&1
fi

if [ "$DEBUGGER" = "y" ]; then
  # Use this instead for ddms and connect by running 'ddms':
  # DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_android_adb,server=y,suspend=y"
  # TODO: add a separate --ddms option?

  PORT=12345
  msg "Waiting for jdb to connect:"
  msg "    adb forward tcp:$PORT tcp:$PORT"
  msg "    jdb -attach localhost:$PORT"
  DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=$PORT,server=y,suspend=y"
fi

if [ "$GDB" = "y" ]; then
    gdb="gdbserver$GDB_TARGET_SUFFIX :5039"
    gdbargs="$exe"
fi

if [ "$INTERPRETER" = "y" ]; then
    INT_OPTS="-Xint"
    if [ "$VERIFY" = "y" ] ; then
      COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=interpret-only"
    else
      COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=verify-none"
      DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
    fi
fi

JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"

if [ "$RELOCATE" = "y" ]; then
  RELOCATE_OPT="-Xrelocate"
  FLAGS="${FLAGS} -Xcompiler-option --include-patch-information"
else
  RELOCATE_OPT="-Xnorelocate"
fi

cmdline="cd $DEX_LOCATION && export ANDROID_DATA=$DEX_LOCATION && export DEX_LOCATION=$DEX_LOCATION && \
    $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $DEX_VERIFY $gdbargs -XXlib:$LIB $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX Main"
if [ "$DEV_MODE" = "y" ]; then
  echo $cmdline "$@"
fi

adb shell $cmdline "$@"