#!/bin/bash
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

function usage() {
  echo "Usage: $0"
  echo
  echo "  Starts up femu.sh, runs a script, captures the result, and terminates the emulator"
  echo
  echo "  [--exec <script>]"
  echo "    Executes the specified script or command that can access the emulator"
  echo "  [--femu-log <file>]"
  echo "    Specify log file instead of mktemp, can also be /dev/null or /dev/stdout"
  echo "  [--headless]"
  echo "    Do not use any graphics support, do not open any new windows"
  echo "  [--interactive]"
  echo "    Opens up xterm window with femu serial console"
  echo "  [--image <name>]"
  echo "    System image to use with femu.sh, defaults to ${IMAGE_NAME}"
  echo
  echo "  All other arguments are passed on, see femu.sh --help for more info"
}

set -eu # Error checking
err_print() {
  echo "Error at $1"
}
trap 'err_print $0:$LINENO' ERR

SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
# shellcheck disable=SC1090
source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?

function get_child_pids {
  children=()
  if is-mac; then
    while IFS='' read -r v; do children+=("$v"); done < <(pgrep -P "$1")
  else
    while IFS='' read -r v; do children+=("$v"); done < <(ps -o pid:1= --ppid "$1")
  fi
  if (( ${#children[@]} )); then
    for pid in "${children[@]}"; do
        while IFS='' read -r v; do children+=("$v"); done < <(get_child_pids "$pid")
    done
    echo "${children[@]}"
  fi
}

# Called when there is an error and we need to dump the log
function dump_femu_log {
  if [[ "${FEMU_LOG}" = /dev/* ]]; then
    echo "Cannot dump log for device ${FEMU_LOG}"
  else
    echo "Dumping log file ${FEMU_LOG}"
    cat -n "${FEMU_LOG}"
  fi
}

# This is only used after femu.sh has been started
function cleanup {
  declare -a CHILD_PIDS=()
  IFS=" " read -r -a CHILD_PIDS <<< "$(get_child_pids "${FEMU_PID}")"
  msg="Cleaning up femu pid ${FEMU_PID}"

  if (( "${#CHILD_PIDS[@]}" )); then
    echo "$msg qemu child processes ${CHILD_PIDS[*]} and package server for exit ..."
    kill "${CHILD_PIDS[@]}" > /dev/null 2>&1  || true
  elif [[ "${FEMU_PID}" != "" ]]; then
    echo "${msg}"
    kill "${FEMU_PID}"  > /dev/null 2>&1 || true
  fi
  "${SCRIPT_SRC_DIR}/fserve.sh" --kill  > /dev/null 2>&1  || true
}

HEADLESS=""
INTERACTIVE=""
EXEC_SCRIPT=""
IMAGE_NAME="qemu-x64"
FEMU_LOG=""
FEMU_LOG_TEMP=""
EMU_ARGS=()

# Check for some of the emu flags, but pass everything else on to femu.sh
while (( "$#" )); do
  case $1 in
    --help|-h)
      usage
      exit 0
    ;;
    --headless)
      HEADLESS="yes"
    ;;
    --interactive)
      INTERACTIVE="yes"
    ;;
    --exec)
      shift
      EXEC_SCRIPT="${1}"
    ;;
    --femu-log)
      shift
      FEMU_LOG="${1}"
    ;;
    --image)
      shift
      IMAGE_NAME="${1}"
    ;;
    *)
      # Everything else is passed on to the emulator
      EMU_ARGS+=( "${1}" )
    ;;
  esac
  shift
done

# This IPv6 address is always generated according to the hash of the qemu network interface in femu.sh
EMULATOR_ADDRESS="fe80::5054:ff:fe63:5e7a%qemu"

# Set up log file if not specified
if [[ "${INTERACTIVE}" == "yes" && "${FEMU_LOG}" != "" && "${FEMU_LOG}" != "/dev/null" ]]; then
  fx-error "--interactive does not write to --femu-log"
  exit 1
fi
if [[ "${FEMU_LOG}" == "" ]]; then
  FEMU_LOG="$(mktemp)"
  FEMU_LOG_TEMP="${FEMU_LOG_TEMP}"
fi

# Always start femu with network access.
femu_command_args=("${SCRIPT_SRC_DIR}/femu.sh" --image "${IMAGE_NAME}" -N)

echo "Starting emulator with logging to ${FEMU_LOG}"
if [[ "${INTERACTIVE}" == "yes" ]]; then
  if (( ${#EMU_ARGS[@]} )); then
    femu_command_args+=("${EMU_ARGS[@]}")
  fi
  # Start up the emulator in the background within a new window, useful for interactive debugging
  xterm -T "femu" -e "${femu_command_args[@]}" &
  FEMU_PID=$!
elif [[ "${HEADLESS}" == "yes" ]]; then
  # When there is no graphics support, run femu in the background with no output visible, and use a software GPU
  femu_command_args+=("--headless" "--software-gpu")
  if (( ${#EMU_ARGS[@]} )); then
    femu_command_args+=("${EMU_ARGS[@]}")
  fi
  "${femu_command_args[@]}" &> "${FEMU_LOG}" < /dev/null &
  FEMU_PID=$!
else
  # Allow femu to open up a window for the emulator and use hardware Vulkan support
  if (( ${#EMU_ARGS[@]} )); then
    femu_command_args+=("${EMU_ARGS[@]}")
  fi
  "${femu_command_args[@]}" &> "${FEMU_LOG}" < /dev/null &
  FEMU_PID=$!
fi
trap cleanup EXIT

# Wait for the emulator to start, and check if emu is still running in the background or this will never complete
echo "Waiting for emulator to start"
COUNT=0
COUNT_TIMEOUT=120
while [[ $COUNT -lt $COUNT_TIMEOUT ]] ; do
  kill -0 ${FEMU_PID} &> /dev/null || ( echo "ERROR: Emulator pid $FEMU_PID has exited, cannot connect"; dump_femu_log; exit 1; )
  "${SCRIPT_SRC_DIR}/fssh.sh" --device-ip "${EMULATOR_ADDRESS}" "echo hello" &> /dev/null && break
  echo "Waiting for emulator SSH server ${EMULATOR_ADDRESS} - attempt ${COUNT} ..."
  COUNT=$((COUNT+1))
  sleep 1s
done
if (( COUNT == COUNT_TIMEOUT )); then
  echo "ERROR: Timeout of ${COUNT_TIMEOUT} seconds reached waiting for emulator pid $FEMU_PID to start, cannot connect"
  dump_femu_log
  exit 1
fi
echo "Emulator pid ${FEMU_PID} is running and accepting connections"

# Start the package server after the emulator is ready, so we know it is configured when we run commands
echo "Starting package server"
"${SCRIPT_SRC_DIR}/fserve.sh" --device-ip "${EMULATOR_ADDRESS}" --image "${IMAGE_NAME}"

# Execute the script specified on the command-line
EXEC_RESULT=0
if [[ "${EXEC_SCRIPT}" == "" ]]; then
  fx-warn "No --exec script specified, will now clean up"
else
  eval "${EXEC_SCRIPT}" "${EMULATOR_ADDRESS}" || EXEC_RESULT=$?
fi

if [[ "${EXEC_RESULT}" != "0" ]]; then
  fx-error "ERROR: \"${EXEC_SCRIPT}\" returned ${EXEC_RESULT}"
  dump_femu_log
else
  # Clean up the temporary file on success
  if [[ "${FEMU_LOG_TEMP}" != "" ]]; then
    rm -f "${FEMU_LOG_TEMP}"
  fi
fi

# Exit with the result of the test script, and also run the cleanup function
exit $EXEC_RESULT
