#!/usr/bin/env bash
#    _ _ _  ___  _ _  _  ___
#   | ' ' |/ . \| '_/| |/ . \
#   |_|_|_|\___/|_|  |_|\___/
#
#   Morio Studio wrapper script
#

set -euo pipefail

CONTAINER_NAME="morio-studio"
DATA_DIR="$HOME/morio/studio"
IMAGE="itsmorio/studio:testing"
PORT=3000

# Make it pretty
if [ -t 1 ]; then
  BOLD="\033[1m"
  DIM="\033[2m"
  CYAN="\033[36m"
  GREEN="\033[32m"
  YELLOW="\033[33m"
  RED="\033[31m"
  RESET="\033[0m"
else
  BOLD="" DIM="" CYAN="" GREEN="" YELLOW="" RED="" RESET=""
fi

# Some helpers
info()    { echo -e "${CYAN}${BOLD}::${RESET} $*"; }
success() { echo -e "${GREEN}${BOLD}✓${RESET}  $*"; }
warn()    { echo -e "${YELLOW}${BOLD}!${RESET}  $*"; }
error()   { echo -e "${RED}${BOLD}✗${RESET}  $*" >&2; }
dim()     { echo -e "${DIM}$*${RESET}"; }

banner() {
  echo
  printf "${CYAN}     _ _ _  ___  _ _  _  ___${RESET}\n"
  printf "${CYAN}    | ' ' |/ . \\| '_/| |/ . \\ ${RESET}\n"
  printf "${CYAN}    |_|_|_|\\___/|_|  |_|\\___/${RESET}\n"
  echo
  dim "     Welcome to Morio Studio"
  echo
}

is_running() {
  docker inspect --format '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null | grep -q "true"
}

# Help
show_help() {
  banner
  if is_running; then
    echo -e "  ${GREEN}${BOLD}●${RESET}  Morio Studio is ${GREEN}${BOLD}running${RESET}"
  else
    echo -e "  ${RED}${BOLD}●${RESET}  Morio Studio is ${RED}${BOLD}not running${RESET}"
  fi
  echo
  echo -e "${BOLD}Usage:${RESET}"
  echo -e "  $(basename "$0") ${CYAN}<sub-command>${RESET}"
  echo
  echo -e "${BOLD}Sub-commands:${RESET}"
  printf "  ${CYAN}%-18s${RESET} %s\n" "start"             "Start Morio Studio"
  printf "  ${CYAN}%-18s${RESET} %s\n" "stop"              "Stop Morio Studio"
  printf "  ${CYAN}%-18s${RESET} %s\n" "reload [thread]"   "Reload stream processor (default thread=1)"
  printf "  ${CYAN}%-18s${RESET} %s\n" "logs [thread]"     "Tail stream processor logs (default thread=1)"
  printf "  ${CYAN}%-18s${RESET} %s\n" "status"            "Show running threads"
  printf "  ${CYAN}%-18s${RESET} %s\n" "bash"              "Start a bash shell inside the container"
  printf "  ${CYAN}%-18s${RESET} %s\n" "pull"              "Forces a pull of the latest Morio Studio container image"
  printf "  ${CYAN}%-18s${RESET} %s\n" "help"              "Show this help message"
  echo
  echo -e "${BOLD}FYI:${RESET}"
  dim "  Container port:  ${YELLOW}$PORT${RESET}${RESET}"
  dim "  Data folder:     ${YELLOW}$DATA_DIR${RESET}"
  dim "  URL:             ${YELLOW}http://`hostname -f`:$PORT${RESET}"
  echo
  echo
}

# Sub-commands
cmd_stop() {
  info "Stopping ${BOLD}Morio Studio${RESET}"
  docker rm -f  "$CONTAINER_NAME" > /dev/null
  success "Morio Studio stopped - container removed"
}

cmd_reload() {
  info "Reloading ${BOLD}Morio Studio${RESET} stream processors"
  docker exec "$CONTAINER_NAME" pm2 reload 0
}

cmd_status() {
  docker exec "$CONTAINER_NAME" pm2 ls
}

cmd_bash() {
  docker exec -it "$CONTAINER_NAME" bash
}

cmd_pull() {
  info "Stopping ${BOLD}Morio Studio${RESET}"
  docker rm -f  "$CONTAINER_NAME" > /dev/null
  success "Morio Studio stopped"
  info "Removing ${BOLD}$IMAGE${RESET} container image"
  docker image rm $IMAGE
  success "Image removed"
  cmd_start
}

cmd_start() {
  # Create the data directory
  if [ ! -d "$DATA_DIR" ]; then
    info "Creating data directory: ${BOLD}$DATA_DIR${RESET}"
    mkdir -p "$DATA_DIR"
    success "Directory created."
  fi

  # Launch container
  info "Pulling image and starting container..."
  docker run -d \
    --name "$CONTAINER_NAME" \
    -p "${PORT}:${PORT}" \
    -v "${DATA_DIR}:/data" \
    "$IMAGE" > /dev/null

  success "Container ${BOLD}$CONTAINER_NAME${RESET} is now running"
  echo
  echo -e "  ${BOLD}Studio URL  :${RESET}  ${CYAN}http://`hostname -f`:${PORT}${RESET}"
  echo -e "  ${BOLD}Data dir    :${RESET}  ${DATA_DIR}"
  echo -e "  ${BOLD}Logs        :${RESET}  ${DATA_DIR}/logs"
  echo
  dim  "  Run  $(basename "$0") help  to see available sub-commands."
  echo
}

cmd_logs() {
  local n="${1:-1}"
  local logfile="$DATA_DIR/logs/tap-${n}.log"

  if [[ ! "$n" =~ ^[0-9]+$ ]]; then
    error "Argument to 'logs' must be a number, got: ${n}"
    exit 1
  fi

  if [ ! -f "$logfile" ]; then
    warn "Log file not found yet: $logfile"
    warn "It will appear once the studio has written its first entries."
    exit 1
  fi

  info "Tailing ${BOLD}$logfile${RESET}  (Ctrl-C to stop)"
  tail -f "$logfile"
}


# Handle sub-commands
SUB="${1:-help}"

case "$SUB" in
  start)
    if is_running; then
      warn "Morio Studio is already running"
      exit 0
    fi
    cmd_start
    ;;
  bash)
    cmd_bash
    ;;
  status)
    cmd_status
    ;;
  stop)
    cmd_stop
    ;;
  pull)
    cmd_pull
    ;;
  reload)
    cmd_reload
    ;;
  logs)
    cmd_logs "${2:-1}"
    ;;
  help|--help|-h)
    show_help
    ;;
  *)
    error "Unknown sub-command: ${BOLD}${SUB}${RESET}"
    show_help
    exit 1
    ;;
esac
