#!/bin/bash -u
# cannot use set dash e with heredoc read variable assignment
# vim:ts=2:sw=2:et:ft=sh:

CWD=$(dirname $0)
TOP=${CHARM_DIR}
COMMAND=$(basename $0)

# there's some hardcoded XML that depends on this so not
# exposing this for now
PTSDIR="/root/.phoronix-test-suite"
PTSARCHIVE="/root/phoronix-archive"

# crazy right? :)
# http://stackoverflow.com/questions/1167746/how-to-assign-a-heredoc-value-to-a-variable-in-bash
# http://peterpetrakis.blogspot.com/2013/07/execute-complex-python-or-ruby-code.html
read -r -d '' upstart_status <<'EOF'
import sys, re
import traceback
from subprocess import Popen, PIPE
try:
  state = sys.stdin.read().rstrip('\n')
  g = re.match('^([\w-]+)(\s[\w+\/]+)(, \w+ \d+)?',state).groups()
  # it always returns array.len = 3, if the last one isn't None, it's running
  if g[-1] is not None:
    print 'running'
  else:
    print 'stopped'
except Exception:
  print 'running' # assume busted
  exc_type, exc_value, exc_traceback = sys.exc_info()
  lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
  cmd = 'juju-log %s' % lines
  Popen(cmd.split(), stdout=PIPE)
EOF

build_testsuites() {
  pts_mode=$(config-get pts_mode)
  juju-log "pts: building test config: ${pts_mode}"

  if [ $pts_mode = 'full' ]; then
    # get each one and concat it all with some space padding
    local sys=$(config-get pts_sys)
    local cpu=$(config-get pts_cpu)
    local mem=$(config-get pts_mem)
    local io=$(config-get pts_io)

    echo "${sys} ${cpu} ${mem} ${io}"

  elif [ $pts_mode = 'custom' ]; then
    local tmp=$(config-get pts_custom)
    if [ -z $tmp ]; then
      echo " " # otherwise facter gets angry
    else
      echo "${tmp}"
    fi
  else
    # we default to something sensible
    echo $(config-get pts_smoke)
  fi
}

# I know I could have just used vars for this but this
# was a facter proving ground, the simplist possible use.
install_job() {
  local job=/etc/init/cabs-runner.conf
  rm -f $job
  # the quotes around EOF suppress shell expansion
  tee $job <<'EOF'
# run test suite
description "Run phoronix test suite"

task

script
  mv -f /tmp/*tgz $(facter phoronix-archive) || :
  PTSRESULTS="/tmp/pts-results-$(uname -n)-$(date +%y%m%d%H%M%S).tgz"
  rm -rf  $(facter phoronix-testdir) || :
  cp -Rpf $(facter phoronix-source)  $(facter phoronix-testdir) || :
  echo 'Y N N' | phoronix-test-suite batch-install   $(facter phoronix-testsuite)
  phoronix-test-suite batch-run $(facter phoronix-testsuite)
  tar cvf - $(facter phoronix-testdir) | gzip -c > "$PTSRESULTS"
  chmod 775 /tmp/*tgz || :
end script
EOF
}

start_test() {
  juju-log "pts: starting test run - `date +%y%m%d%H%M%S`"
  initctl stop cabs-runner || :
  initctl start --no-wait cabs-runner || :
}

stop_test() {
  juju-log "pts: stopping test run - `date +%y%m%d%H%M%S`"
  initctl stop cabs-runner || :
}

clear_facts() {
  juju-log "puppet facter reset"
  fact-del phoronix-testsuite 2>&1 > /dev/null || :
  fact-del phoronix-testdir   2>&1 > /dev/null || :
}

install_phoronix() {
  juju-log "installing phoronix"
  clear_facts
  stop_test
  apt-get -qq update
  apt-get install -qqy unzip build-essential default-jre-headless mesa-utils
  apt-get install -qqy phoronix-test-suite

  apt-get install -qqy python python-pip
  pip install --upgrade charms.benchmark

  # puppet helper to distribute facts between scripts
  apt-get install -qqy facter-customfacts-plugin

  # install this to allow querying via upstart to proceed
  # for whatever reason, even though we're in 'config'
  # when we enter config_changed, the initial job isn't
  # created until we actually setup or run a test
  install_job

  install --mode=775 -d $PTSARCHIVE
  fact-add phoronix-source  "$TOP/files/dotfile-phoronix-test-suite"
}

config_changed_phoronix() {
  # if we change this while a test is running we can't stop it
  # as upstart loses track of the pids

  # We are devolving a bit in the meanwhile because of a newly
  # discovered bug in juju config where it coalesces config-set
  # under some circumstances making a deterministic interface
  # impossible.
  #
  # Until the benchmark-control interface is deployed... If you
  # try to do a config-set while the benchmark is running, config-changed
  # hook will simply die, prompting external intervention
  local state=$(initctl status cabs-runner | python -c "$upstart_status")
  juju-log "phoronix is $state"
  [ $state == 'running' ] && exit 1

  juju-log 'configuring pts'

  local suite=$(build_testsuites)
  fact-add phoronix-archive        "$PTSARCHIVE"
  fact-add phoronix-testsuite      "$suite"
  fact-add phoronix-testdir        "$PTSDIR"

  juju-log "confirm benchmark settings"
  juju-log "archive: $(facter phoronix-archive)"
  juju-log "suite:   $(facter phoronix-testsuite)"
  juju-log "dir:     $(facter phoronix-testdir)"
}

case $COMMAND in
  install)
    install_phoronix
    ;;
  start)
    juju-log "starting phoronix is a nop, use the upstart job"
    ;;
  stop)
    juju-log "starting phoronix is a nop, use the upstart job"
    ;;
  config-changed)
    config_changed_phoronix
    ;;
  upgrade-charm)
    install_phoronix
    ;;
  *)
    juju-log "command not recognized"
esac

exit 0
