#!/bin/bash

. /opt/sys/lib/sh/log.lib

maxWait=10
progName=$(basename $0)

showhelp () {

project=codebase

cat <<EOF

  ${progName} - run the Hugo static site generator in server mode

  usage: ${progName} <command> -c <config file>
         ${progName} --help

  where <command> is either 'start' or 'stop' to start/stop Hugo and
  <config file> is the configuration file to start Hugo with. The
  configuration has to be located in the root of the site project
  directory.

  Options

  -c | --config     the configuration file to start Hugo with. Has to be
                    located in the root of the site project directory.

  -m | --maxWait    maximum time in seconds to wait for hugo to start up.
                    if hugo startup exceeds the maximum time, startup is
                    aborted. The default is 10 seconds, which is fine for
                    small sites. This parameter needs only to be set for
                    larger sites, where a successful hugo startup takes
                    longer than the default 10 seconds.

  -h | --help       prints the online help you are reading right now.

  Config file values, all of them are mandatory

  project           the project name. Can be any value without whitespaces.
  logFile           the HUGO log file.

  the following config file values have the same meaning as in HUGO:

  baseUrl
  bind
  port
  chacheDir

  sample config file:

  project=codebase
  baseUrl="http://idoru"
  bind=192.168.0.10
  port=9494
  cacheDir=/tmp
  logFile=/tmp/hugo-dev.\${project}.log"

  the config file is sourced, so in the example above, in the value
  for logFile, \${project} is expanded to 'codebase', thus the value
  for the logFile is '/tmp/hugo-dev.codebase.log'

  hugoctl creates and uses a tmp dir named 'hugo-cache-${project}' inside
  the tmp dir specified in the config file.

EOF
}

## get options

while [[ $# -gt 0 ]]
do
  key="$1"

  case ${key} in

    -c|--config)
      shift
      configFile="$1"
      shift
      ;;

    -m|--maxWait)
      shift
      maxWait="$1"
      shift
      ;;

    -h|--help)
      showhelp
      exit 0
      ;;

    start)
      command="start"
      shift
      ;;

    stop)
      command="stop"
      shift
      ;;

    *)    # unknown option
      printf "\n\nunknown option '%s'\n\n" ${key}
      exit 2
      ;;

  esac
done

[[ -z ${command} ]]      && log_fail "command not set" && exit 1
[[ -z ${configFile} ]]   && log_fail "config file not set" && exit 1

[[ ! -r ${configFile} ]] && log_fail "config file does not exist or don't have read permissions for it" && exit 1


. ${configFile}

projectDir=$( dirname ${configFile} )
cacheDir=/tmp/hugo-cache-${project}

cd ${projectDir} >/dev/null 2>&1


start() {

  # if port is already in use, bail out

  ss -tulpn | grep "192.168.0.10:${port}" > /dev/null 2>&1
  check=$?

  if [[ ${check} -eq 0 ]]; then

    log_warn "port ${port} is already in use. not going to start any process for hugo"
    log_info "check if hugo for project '${project}' is already running"
    cd - >/dev/null 2>&1
    exit 1
  fi

  log_info "starting hugo for project '${project}'"

  hugo server --logFile=${logFile} --cacheDir ${cacheDir} --bind ${bind} --baseUrl http://idoru -p ${port} > /dev/null 2>&1 &

  log_info "waiting max. ${maxWait} seconds for hugo to fire up ... "

  running=0
  loop=0

  # move cursor to end of last log_info output line and save cursor position
  tput cuu 1
  tput cuf 55
  tput sc

  while [[ ${running} -eq 0 && ${loop} -lt ${maxWait} ]]
  do
    sleep 1
    loop=$((${loop} + 1))

    # restore cursor position and clear to end of line
    tput rc
    tput el
    printf "%s secs elapsed" ${loop}

    # check if port for Hugo is in use

    ss -tulpn | grep "192.168.0.10:${port}" > /dev/null 2>&1
    check=$?
    [[ ${check} -eq 0 ]] && running=1

  done


  if [[ ${check} -eq 0 ]]; then

    log_ok   "hugo for project '${project}' is up and running. listening on port ${port}"
    log_info "staging project available under URL http://idoru:${port}/"
    log_info "hugo log file is ${logFile}"

  else

    log_fail "hugo for project '${project}' did not start up"
    log_info "you can check the log file ${logFile} for information about the startup failure"
  fi

  cd - >/dev/null 2>&1
}

stop() {

  # if port is not in use, bail out

  ss -tulpn | grep "192.168.0.10:${port}" > /dev/null 2>&1
  check=$?

  if [[ ${check} -eq 1 ]]; then

    log_warn "port ${port} is not in use. no process killed"
    log_warn "check if hugo for project '${project}' is running"

    cd - >/dev/null 2>&1
    exit 1
  fi

  log_info "terminating hugo for project '${project}'"
  log_info "port: ${port}"


  pid=$(ps ax | grep "http://idoru -p "${port} | sed -n '/hugo server/p' | awk '{print $1}')

  log_info "pid : ${pid}"

  kill ${pid}

  log_info "waiting max ${maxWait} seconds for hugo to terminate ..."

  running=1
  loop=0

  while [[ ${running} -eq 1 && ${loop} -lt ${maxWait} ]]
  do
    sleep 1

    # check if port for Hugo is in use

    ss -tulpn | grep "192.168.0.10:${port}" > /dev/null 2>&1
    check=$?
    [[ ${check} -eq 1 ]] && running=0

    loop=$((${loop} + 1))
  done


  if [[ ${check} -eq 1 ]]; then

    log_ok "killed process with pid ${pid}"
    rm -r ${cacheDir}
  else

    log_fail "process with pid ${pid} still running"
  fi
}


case ${command} in

  start)
    start
    ;;

  stop)
    stop
    ;;

esac

cd - >/dev/null 2>&1

