#!/usr/bin/env bash
# to be included by install.sh


####                                                             ####
#                                                                   #
#                          FUNCTIONS, etc.                          #
#                                                                   #
####                                                             ####


# heredoc for variables - very readable, http://stackoverflow.com/a/8088167
# use like this:
# define VAR <<'EOF'
# somecontent
# EOF
define(){ IFS='\n' read -r -d '' ${1}; }


# add padding to the left of a given string to
# fill to a given amount of characters with a
# given char or space
# example:
#   lpad 7 "test" "-"
lpad() {
  LEN=$1
  TXT=$2
  CHR=$3
  PAD=""

  L_PAD=$(($LEN - ${#TXT}))
  if [ $L_PAD -ne 0 ] ; then
    PAD=$(printf "%*s" ${L_PAD} " ")
  fi
  if [ ${#CHR} -ne 0 ] ; then
    PAD=$(printf "$PAD" | tr " " "$CHR")
  fi
  PAD="${PAD}${TXT}"

  printf "%s" "$PAD"
}


# log function
# prints a given message with the given log level to STDOUT
logf() {
  MSG=$1
  LVL=$2
  L_LEN=7

  if [ ${#LVL} -ne 0 ] ; then
    LVL="[$(lpad $(($L_LEN-2)) $LVL " ")]"
  else
    LVL=$(lpad $L_LEN "" "-")
  fi

  printf "%s -- %s\\n" "$LVL" "$MSG"
}

# short functions for various log levels
log_err() {
  logf "$1" "error"
}

log_wrn() {
  logf "$1" "warn"
}

log_dbg() {
  logf "$1" "debug"
}

log_inf() {
  logf "$1" "info"
}


# run a command or print the error
run_or_error() {
  eval "$1"
  if [ $? -ne 0 ]; then
    error "executing '$1' failed."
  fi
}

# nicely output error messages and quit
error() {
  log_err "$1"
  logf "have a look at our wiki: $D_WIKI_URL"
  logf "or join us on IRC: $D_IRC_URL"
  exit 1
}


# check for functions
fn_exists() {
  type -t $1 | grep -q 'function'
}


# shell interactive or not
interactive_check() {
  fd=0 #stdin
  if [[ -t "$fd" || -p /dev/stdin ]]; then
    # all is well
    printf "\n"
  else
    # non-interactive
    TMPFILE=`mktemp`
    curl -s -o "$TMPFILE" "$D_INSTALL_SCRIPT_URL"
    chmod +x "$TMPFILE"
    exec 0< /dev/tty
    bash -i "$TMPFILE"
    rm "$TMPFILE"
    exit 0
  fi
}


# check if this script is run as root
root_check() {
  if [ `id -u` -eq 0 ] ; then
    error "don't run this script as root!"
  fi
}


# check if all necessary binaries are available
binaries_check() {
  for exe in "${!BINARIES[@]}"; do
    LOG_MSG="checking for $exe... "
    log_inf "$LOG_MSG"

    EXE_PATH=$(which "${BINARIES[$exe]}")
    if [ $? -ne 0 ]; then
      error "you are missing the '${BINARIES[$exe]}' command, please install '$exe'";
    else
      printf "$ONE_UP"
      log_inf "$LOG_MSG  found"
    fi
  done
  printf "\n"
}


# check for rvm
rvm_check() {
  LOG_MSG="checking for rvm... "
  log_inf "$LOG_MSG"

  fn_exists rvm
  if [ $? -eq 0 ] ; then
    RVM_DETECTED=true

  # seems we don't have it loaded, try to do so
  elif [ -s "$HOME/.rvm/scripts/rvm" ] ; then
    source "$HOME/.rvm/scripts/rvm" >/dev/null 2>&1
    RVM_DETECTED=true
  elif [ -s "/usr/local/rvm/scripts/rvm" ] ; then
    source "/usr/local/rvm/scripts/rvm" >/dev/null 2>&1
    RVM_DETECTED=true
  fi

  if $RVM_DETECTED ; then
    printf "$ONE_UP"
    log_inf "$LOG_MSG  found"
  else
    log_wrn "not found"
    logf "$RVM_MSG"
    read -p "Press [Enter] to continue without RVM or abort this script and install RVM..."
  fi
  printf "\n"
}


# prepare ruby with rvm
install_or_use_ruby() {
  if ! $RVM_DETECTED ; then
    return
  fi

  # make sure we have the correct ruby version available
  LOG_MSG="checking your ruby version... "
  log_inf "$LOG_MSG"

  rvm use $D_RUBY_VERSION >/dev/null 2>&1
  if [ $? -ne 0 ] ; then
    log_wrn "not ok"
    rvm --force install $D_RUBY_VERSION
  else
    printf "$ONE_UP"
    log_inf "$LOG_MSG  ok"
  fi

  printf "\n"
}


# trust and load rvmrc
# do this in a directory that has a .rvmrc, only :)
load_rvmrc() {
  if ! $RVM_DETECTED || [[ ! -s ".rvmrc" ]] ; then
    return
  fi

  # trust rvmrc
  rvm rvmrc is_trusted
  if [ $? -ne 0 ] ; then
    rvm rvmrc trust
  fi

  # load .rvmrc
  LOG_MSG="loading .rvmrc ... "
  log_inf "$LOG_MSG"

  . ".rvmrc"
  #rvm rvmrc load
  if [ $? -eq 0 ] ; then
    printf "$ONE_UP"
    log_inf "$LOG_MSG  ok"
  else
    log_wrn "not ok"
  fi
  printf "\n"
}


# rvm doesn't need sudo, otherwise we do have to use it :(
rvm_or_sudo() {
  if $RVM_DETECTED ; then
    run_or_error "$1"
  else
    eval "$1"
    if [ $? -ne 0 ] ; then
      log_wrn "running '$1' didn't succeed, trying again with sudo..."
      run_or_error "sudo $1"
    fi
  fi
}


# we need a valid js runtime...
js_runtime_check() {
  LOG_MSG="checking for a JavaScript runtime... "
  log_inf "$LOG_MSG"

  # Node.js
  which node >/dev/null 2>&1
  if [ $? -eq 0 ] ; then
    JS_RUNTIME_DETECTED=true
  fi

  # TheRubyRacer
  (printf "require 'v8'" | ruby) >/dev/null 2>&1
  if [ $? -eq 0 ] ; then
    JS_RUNTIME_DETECTED=true
  fi

  ##
  # add a check for your favourite js runtime here...
  ##

  if $JS_RUNTIME_DETECTED ; then
    printf "$ONE_UP"
    log_inf "$LOG_MSG  found"
  else
    log_err "not ok"
    printf "$JS_RT_MSG"
    error "can't continue without a JS runtime"
  fi
  printf "\n"
}
