#!/usr/bin/env bash
# How to run:
#
#  ./bootandkill-servers ./test-acceptance
#
# this will boot hexo & companion, run the script that you provided as an argument,
# and tear down the servers

set -o pipefail
set -o errexit
set -o nounset
set -o xtrace

# Set magic variables for current file & dir
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname "${__dir}")" && pwd)"

if [ ! -f "${__root}/env.sh" ]; then
  cp "${__root}/env.example.sh" "${__root}/env.sh"
fi
if [ "${COMPANION_DROPBOX_KEY:-}" = "" ] || [ "${COMPANION_DROPBOX_KEY:-***}" = "***" ]; then
  source "${__root}/env.sh"
fi
if [ "${COMPANION_DROPBOX_KEY:-}" = "" ] || [ "${COMPANION_DROPBOX_KEY:-***}" = "***" ]; then
  echo "[${__base}] Env var COMPANION_DROPBOX_KEY still had the example value '${COMPANION_DROPBOX_KEY:-}'. "
  echo "[${__base}] Please save the actual secrets in '${__root}/env.sh' and try again"
  exit 1
fi

function killProcessListeningOnPort () {
  local port="${1}"
  lsof -n -i4TCP:${port} | awk '/LISTEN/ {print $2}' |xargs --no-run-if-empty kill -9 || true
}

function cleanup_servers () {
  echo "[${__base}] --> Killing any server listening on port 4000"
  killProcessListeningOnPort 4000 || true

  echo "[${__base}] --> Killing any server listening on port 3020"
  killProcessListeningOnPort 3020 || true

  kill -9 ${tailPid}
}

function waitForPortOpen () {
  local port="${1}"
  local limit="${2:-100}"
  local attempts=0
  echo "[${__base}] waiting on port ${port} to open... "
  while ! echo exit | nc localhost ${port}; do
    let "attempts = attempts + 1"
    echo "[${__base}] still waiting on port ${port} to open... (${attempts} / ${limit}) "
    sleep 1
    if [ "${attempts}" -ge "${limit}" ]; then
      echo "[${__base}] --> Port did not open for ${limit} seconds. Aborting. "
      exit 1
    fi
  done
}

echo "[${__base}] --> Killing any server listening on port 4000"
killProcessListeningOnPort 4000 || true
echo "[${__base}] --> Killing any server listening on port 3020"
killProcessListeningOnPort 3020 || true

echo "[${__base}] --> Start webserver and companion in the background"
rm -f nohup.out || true
touch nohup.out
nohup npm run test:serve &
tail -f nohup.out &
tailPid=${!}

trap cleanup_servers EXIT



echo "[${__base}] --> Wait for hexo webserver to be online"
waitForPortOpen 4000

echo "[${__base}] --> Wait for companion to be online"
waitForPortOpen 3020

echo "[${__base}] --> Running acceptance tests"


buildWait=20
if [ "${TRAVIS:-}" = "true" ]; then
  buildWait=60
  echo "Increasing build wait because Travis has no Hexo build cache"
fi

echo "[${__base}] --> Sleeping ${buildWait}s, because the port may be open, but Hexo may still be injecting/building stuff"
echo "[${__base}] --> and I don't know yet how to check for that"
sleep ${buildWait}

# @todo: Instead of this `sleep` we can wait until the required files are in public : )

${@}
