#!/usr/bin/env bash

set -e

# Path usage adheres to freedesktop.org XDG Base Directory Specification
# https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
SMALL_TECH_DATA_HOME="${DATA_HOME}/small-tech.org"
KITTEN_DATA_HOME="${SMALL_TECH_DATA_HOME}/kitten"
KITTEN_RUNTIME_DIRECTORY="${KITTEN_DATA_HOME}/runtime"
KITTEN_BIN_DIRECTORY="${KITTEN_RUNTIME_DIRECTORY}/bin"
KITTEN_RUNTIME="${KITTEN_BIN_DIRECTORY}/node"

# Save the base path so we can pass it to Kitten so it can calculate the
# absolute path of the path to serve even if a relative path is given from
# the current working directory.
workingDirectory=$(pwd)

# Run Kitten from Kitten distribution folder not folder kitten command
# was run from.
pushd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" > /dev/null

# Run either the kitten bundle directly (in production), or run the
# kitten-process-manager (in development) which will restart Kitten
# in place of systemd.
# Note that the 0x flame graph module does not work with node cluster
# and thus cannot be used in development mode (we use node cluster to
# implement the development-time process manager).
mainProcess='./kitten-process-manager.js'

# If the person wants to run a command other than serve during
# development, we load the main bundle directly. Given that the
# serve command is the default and any path could be supplied
# as the first argument, we have to manually check for all supported
# commands. This introduces a bit of redundancy and maintenance headache
# by replicating the command names from cli/index.js but it is,
# currently, the best we can do. Just remember you have to update
# the commmand names in two places when you add a new command. 
if [[ "${PRODUCTION}" == 'true' || "${FLAME_GRAPH}" == 'true'
      || "$1" == 'serve' || "$1" == 'run' || "$1" == 'db' || "$1" == '_db'
      || "$1" == 'deploy' || "$1" == 'status' || "$1" == 'logs' || "$1" == 'start'
      || "$1" == 'stop' || "$1" == 'restart' || "$1" == 'enable' || "$1" == 'disable'
      || "$1" == 'update' || "$1" == 'uninstall' || "$1" == 'version' || "$1" == 'help'
      || "$1" == '--version' || "$1" == '--help'
   ]]; then
  mainProcess='./kitten-bundle.js'
fi

# If flame graph is requested, generate it using 0x and
# have it open up in a web browser.
flameGraph=''
if [[ "${FLAME_GRAPH}" == 'true' ]]; then
  kitten-npm install -g 0x # 0x must be globally installed for this to work.
  flameGraph='0x -o --'
fi

# If the debugger is requested (INSPECT=true), run
# Node using the --inspect flag and run the bundle directly.
inspect=''
if [[ "${INSPECT}" == 'true' ]]; then
  inspect='--inspect-brk'
  mainProcess='./kitten-bundle.js'
fi

# Launch Node.
QUIET=true \
NODE_OPTIONS='--require=./suppress-experimental.cjs' \
$flameGraph \
$KITTEN_RUNTIME \
$inspect \
--experimental-modules \
--loader ./loader-bundle.js \
"${mainProcess}" \
--working-directory="${workingDirectory}" \
"$@"

# Return to folder Kitten was evoked from when execution ends.
trap 'popd > /dev/null' EXIT
