#!/bin/bash

# Copyright (C) 2023 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function die() {
  echo "${@}" >&2
  exit 1;
}

function run_cmd_or_die() {
  "${@}" > /dev/null || die "Command failed: ${*}"
}

function run_cmd_with_retries() {
  echo "Executing ${@}..."
  while true; do
    "${@}" && break || {
      echo "  Retrying ${@}"
      sleep 10;
    }
  done
}

function select_device() {
  while :; do
    read -r -p "Select a device to install the ${1} app (0-${DEVICE_COUNT}): " INDEX
    [[ "${INDEX}" =~ ^[0-9]+$ ]] && ((INDEX >= 0 && INDEX <= DEVICE_COUNT)) && return "${INDEX}"
  done
}

function install_app() {
  if ! adb -s "${1}" install -r -d -g "${2}" > /dev/null; then
    adb -s "${1}" uninstall "com.example.android.vdmdemo.${3}" > /dev/null 2>&1
    run_cmd_or_die adb -s "${1}" install -r -d -g "${2}"
  fi
}

function display_help() {
  echo "Setup helper for the VirtualDeviceManager host and client applications."
  echo ""
  echo "  -s, --host):         Setup the host application on the only device connected via ADB."
  echo "  -c, --client):       Setup the client application on the only device connected via ADB."
  echo "  -a, --all):          Setup all available demo apps: host, client, and demos."
  echo "  -i, --install-only): Only install the selected application. Will not perform any build."
  echo "  -h, --help):         Print this help."
}

function display_available_devices() {
    echo
    echo "Available devices:"
    for i in "${!DEVICE_SERIALS[@]}"; do
      echo -e "${i}: ${DEVICE_SERIALS[${i}]}\t${DEVICE_NAMES[${i}]}"
    done
    echo "${DEVICE_COUNT}: Do not install this app"
    echo
}

function privileged_install() {
  local TARGET_DEVICE_SERIAL="${1}"
  local TARGET_DEVICE_NAME="${2}"
  local APK_DIR="${3}"
  local APK_FILENAME="${4}"
  local PERM_SRC="${5}"
  local PERM_DST="${6}"
  local PKG_NAME="com.example.android.vdmdemo.${7}"

  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device root
  if ! adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell touch /system/test_verity > /dev/null; then
    echo "Disabling verity..."
    run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device disable-verity
    run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device reboot
    run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device root
  else
    run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell rm /system/test_verity
    echo "Verity is already disabled"
  fi

  adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device uninstall "${PKG_NAME}" > /dev/null 2>&1

  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device remount -R
  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell stop
  echo 'Copying privileged permissions and apk...'
  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell mkdir -p "${APK_DIR}"
  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device push "${OUT}/${APK_DIR}/${APK_FILENAME}" "${APK_DIR}"
  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device push "${PERM_SRC}" "${PERM_DST}"
  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell start
  echo "Installing ${APK_FILENAME} as a privileged app to ${TARGET_DEVICE_NAME}..."
  run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell pm install -r -g -d "${APK_DIR}/${APK_FILENAME}"
  echo
}


if [[ ! -f build/make/envsetup.sh ]] ; then
  if [[  -n ${ANDROID_BUILD_TOP} ]] ; then
    cd ${ANDROID_BUILD_TOP}
  else
    die "Run this script from the root of the tree."
  fi
fi

INSTALL_HOST=true
INSTALL_CLIENT=true
PERFORM_BUILD=true
while [[ "$#" -gt 0 ]]; do
    case $1 in
        -h|--help) display_help; exit ;;
        -a|--all) shift ;;
        -s|--host) INSTALL_CLIENT=false; shift ;;
        -c|--client) INSTALL_HOST=false; shift ;;
        -i|--install-only) PERFORM_BUILD=false; shift ;;
        *) echo "Unknown parameter passed: $1"; display_help; exit ;;
    esac
done

DEVICE_COUNT=$(adb devices -l | tail -n +2 | head -n -1 | wc -l)
((DEVICE_COUNT > 0)) || die "No devices found"

DEVICE_SERIALS=( $(adb devices -l | tail -n +2 | head -n -1 | awk '{ print $1 }') )
DEVICE_NAMES=( $(adb devices -l | tail -n +2 | head -n -1 | awk '{ print $4 }') )
HOST_SERIAL=""
CLIENT_SERIAL=""
CLIENT_INDEX=$DEVICE_COUNT
HOST_INDEX=$DEVICE_COUNT

if [[ ${INSTALL_HOST} == true ]]; then
  if [[ ${DEVICE_COUNT} -eq 1 ]]; then
    HOST_INDEX=0
  else
    display_available_devices
    select_device "VDM Host"
    HOST_INDEX=$?
  fi
fi
if [[ ${INSTALL_CLIENT} == true ]]; then
  if [[ ${DEVICE_COUNT} -eq 1 ]]; then
    CLIENT_INDEX=0
  else
    display_available_devices
    select_device "VDM Client"
    CLIENT_INDEX=$?
  fi
fi

if ((HOST_INDEX == DEVICE_COUNT)); then
  echo "Not installing host app."
else
  HOST_SERIAL=${DEVICE_SERIALS[HOST_INDEX]}
  HOST_NAME="${HOST_SERIAL} ${DEVICE_NAMES[HOST_INDEX]}"
  echo "Installing VDM Host apps to ${HOST_NAME}."
fi
if ((CLIENT_INDEX == DEVICE_COUNT)); then
  echo "Not installing client app."
else
  CLIENT_SERIAL=${DEVICE_SERIALS[CLIENT_INDEX]}
  CLIENT_NAME="${CLIENT_SERIAL} ${DEVICE_NAMES[CLIENT_INDEX]}"
  echo "Installing VDM Client app to ${CLIENT_NAME}."
fi

APKS_TO_BUILD=""
[[ -n "${HOST_SERIAL}" ]] && APKS_TO_BUILD="${APKS_TO_BUILD} VdmHost VdmDemos"
[[ -n "${CLIENT_SERIAL}" ]] && APKS_TO_BUILD="${APKS_TO_BUILD} VdmClient"
[[ -n "${APKS_TO_BUILD}" ]] || exit 0

if [[ ${PERFORM_BUILD} == true ]];
then
  echo
  echo "Building APKs:${APKS_TO_BUILD}..."
  echo

  source ./build/envsetup.sh || die "Failed to set up environment"
  [[ -n "${ANDROID_BUILD_TOP}" ]] || run_cmd_or_die tapas "${APKS_TO_BUILD}"
  UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m -j "${APKS_TO_BUILD}" || die "Build failed"
else
  echo "Skipping Build"
fi

if [[ -n "${CLIENT_SERIAL}" ]]; then
  echo
  echo "Installing VdmClient.apk to ${CLIENT_NAME}..."
  install_app "${CLIENT_SERIAL}" "${OUT}/system/app/VdmClient/VdmClient.apk" client
fi

if [[ -n "${HOST_SERIAL}" ]]; then
  echo
  echo "Installing VdmDemos.apk to ${HOST_NAME}..."
  install_app "${HOST_SERIAL}" "${OUT}/system/app/VdmDemos/VdmDemos.apk" demos
  echo

  readonly HOST_PERM_BASENAME=VdmHost.xml
  readonly HOST_PERM_SRC="${OUT}/system/etc/permissions/${HOST_PERM_BASENAME}"
  readonly HOST_PERM_DST="/system/etc/permissions/${HOST_PERM_BASENAME}"
  readonly HOST_APK_DIR=/system/priv-app/VdmHost

  echo "Preparing ${HOST_NAME} for privileged VdmHost installation..."
  if adb -s "${HOST_SERIAL}" shell ls "${HOST_APK_DIR}/VdmHost.apk" > /dev/null 2>&1 \
      && adb -s "${HOST_SERIAL}" pull "${HOST_PERM_DST}" "/tmp/${HOST_PERM_BASENAME}" > /dev/null 2>&1 \
      && cmp --silent "/tmp/${HOST_PERM_BASENAME}" "${HOST_PERM_SRC}" \
      && (adb -s "${HOST_SERIAL}" uninstall com.example.android.vdmdemo.host > /dev/null 2>&1 || true) \
      && adb -s "${HOST_SERIAL}" install -r -d -g "${OUT}/${HOST_APK_DIR}/VdmHost.apk" > /dev/null 2>&1; then
    echo "A privileged installation already found, installed VdmHost.apk to ${HOST_NAME}"
    echo
  else
    privileged_install "${HOST_SERIAL}" "${HOST_NAME}" "${HOST_APK_DIR}" \
                       "VdmHost.apk" "${HOST_PERM_SRC}" "${HOST_PERM_DST}" host
  fi
fi

echo
echo 'Success!'
echo
