#!/bin/bash
# Copyright 2017 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.

#### CATEGORY=Other
### serve from a remote workstation

## usage: fx serve-remote [--no-serve] HOSTNAME [REMOTE-PATH]
##
## HOSTNAME     the hostname of the workstation you want to serve from
## REMOTE-PATH  defaults to ~/fuchsia. The path on the to FUCHSIA_DIR on the workstation.
##
##  --no-serve  only tunnel, do not start a package server

source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $?
fx-config-read

serve=true
verbose=false
host=""
dir=""
while [[ $# -ne 0 ]]; do
  case "$1" in
  --help|-h)
      fx-command-help
      exit 0
      ;;
  --no-serve)
    serve=false
    ;;
  -v)
    verbose=true
    ;;
  -*)
    fx-error "Unknown flag: $1"
    fx-command-help
    exit 1
    ;;
  *)
    if [[ -z "${host}" ]]; then
      host="$1"
    elif [[ -z "${dir}" ]]; then
      dir="$1"
    else
      fx-error "unexpected argument: '$1'"
      exit 1
    fi
    ;;
  esac
  shift
done

if [[ -z "${host}" ]]; then
  fx-error "HOSTNAME must be specified"
  fx-command-help
  exit 1
fi

if "${serve}"; then
  if [[ -z "${dir}" ]]; then
    if ssh "$host" ls \~/fuchsia/.jiri_root/bin/fx > /dev/null; then
      dir="~/fuchsia"
    else
      fx-error "failed to find ~/fuchsia on $host, please specify REMOTE-DIR"
      fx-command-help
      exit 1
    fi
  fi
fi

target_addr=$(get-fuchsia-device-addr)
if [[ $? -ne 0 || -z "${target_addr}" ]]; then
  fx-error "unable to discover device. Is the target up?"
  exit 1
fi

echo "Using remote ${host}:${dir}"
echo "Using target device $(get-device-name)"


# Use a dedicated ControlPath so script can manage a connection seperately from the user's. We
# intentionally do not use %h/%p in the control path because there can only be one forwarding
# session at a time (due to the local forward of 8083).
ssh_base_args=(
  "${host}"
  -S "~/.ssh/control-fuchsia-fx-remote"
  -o ControlMaster=auto
)

ssh_exit() {
  ssh ${ssh_base_args[@]}  -O exit > /dev/null 2>&1
}

# If there is already control master then exit it. We can't be sure its to the right host and it
# also could be stale.
ssh_exit

# When we exit the script, close the background ssh connection.
trap_exit() {
  ssh_exit
  exit
}
trap trap_exit EXIT

ssh_tunnel_args=(
  -6 # We want ipv6 binds for the port forwards
  -L "\*:8083:localhost:8083"     # fx serve
  -R "8022:[${target_addr}]:22"   # fx shell
  -R "2345:[${target_addr}]:2345" # fx debug
  -R "8007:[${target_addr}]:8007" # Google-specific
  -R "8443:[${target_addr}]:8443" # Google-specific
  -R "9080:[${target_addr}]:80"   # SL4F_HTTP_PORT
  -o ExitOnForwardFailure=yes
  # Match google default server timeout so in spotty network situations the client doesn't timeout
  # before server (and leave the server process still holding on to tunneling port).
  -o ServerAliveInterval=30
  -o ServerAliveCountMax=20
)

# Start tunneling session in background. It's started seperately from the command invocations below
# to allow the script to be consistent on how it is exited for both serve and non-serve cases. It
# also allows script to explicitly close the control session (to better avoid stale sshd sessions).

# Use `&` in addition to `-f` so so ssh doesn't receive script's SIGINT. And then `wait` to ensure
# tunnels are established before continuing.
ssh ${ssh_base_args[@]} ${ssh_tunnel_args[@]} -nNTf &
wait $!

# If the user requested serving, then we'll check to see if there's a
# remote server already running and kill it, this prevents most cases where
# signal propagation seems to sometimes not make it to "pm".
# TODO(drees) This can be combined with the serve-updates call later to reduce ssh calls.
if "${serve}" && ssh ${ssh_base_args[@]} 'ss -ln | grep :8083' > /dev/null; then
  ssh "${ssh_base_args[@]}" 'pkill -x -u $USER pm'
fi

if "${serve}"; then
  # Ctrl-C will exit the ssh remote command and this ssh session. Then script exit will trigger
  # `trap_exit` to close the ssh connection.
  echo -e "Press Ctrl-C to stop remote serving and tunneling.\n"
  if "${verbose}"; then
    serve_verbose_arg=" -v"
  else
    serve_verbose_arg=""
  fi
  ssh_serve_args=(
    "-tt" # explicitly force a pty, for HUP'ing on the remote
    "cd ${dir} && ./.jiri_root/bin/fx set-device '[::1]:8022' && ./.jiri_root/bin/fx serve-updates${serve_verbose_arg}"
  )
  ssh ${ssh_base_args[@]} ${ssh_serve_args[@]}
else
  echo "Press Ctrl-C to stop tunneling."
  # Wait for user Ctrl-C. Then script exit will trigger trap_exit to close the ssh connection.
  read -r -d '' _ </dev/tty
fi
