#!/bin/bash
# WF 2019-09-17
# improved WF 2023-05-26
# test gremlin-python

# see https://stackoverflow.com/questions/57936915/how-do-i-get-gremlin-python-with-gremlin-server-3-4-3-to-work
version=3.6.4
mirror=https://dlcdn.apache.org/tinkerpop/$version
gsd=apache-tinkerpop-gremlin-server-${version}
gcd=apache-tinkerpop-gremlin-console-${version}
# python and pip commands to be used
# on macports see e.g. http://johnlaudun.org/20150512-installing-and-setting-pip-with-macports/ for how to modify these
# e.g. with sudo port select --set pip3 pip37
pip=pip3
python=python3
pyversion=3.9

if [ "$USER" = "travis" ]
then
  pip=pip
  python=python
fi

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'
red='\033[0;31m'
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}

# error
#
#   show an error message and exit
#
#   params:
#     1: l_msg - the message to display
error() {
  local l_msg="$1"
  # use ansi red for error
  color_msg $red "Error: $l_msg" 1>&2
}

#
# show the usage
#
usage() {
  echo "usage: $0  [-c|-h|-i|-n|-p|-s|-t|-v]"
  echo "  -c|--console: start groovy console"
  echo "  -cd|--console_docker: start groovy console via docker"
  echo "  -h|--help: show this usage"
  echo "  -i|--install: install prerequisites"
  echo "  -n|--neo4j: start neo4j server"
  echo "  -p|--python: start python trial code"
  echo "  -s|--server: start server"
  echo "  -sd|--server_server: start server via docker"
  echo "  -t|--test: start pytest"
  echo "  -v|--version: show version"
  exit 1
}

#
# checkinstalled
#
#  check that l_prog is available by calling which
#  if not available install from given package depending on Operating system
#
#  params:
#    1: l_prog: The program that shall be checked
#    2: l_version: The option to check the version of the program
#    3: l_linuxpackage: The apt-package to install from
#    4: l_macospackage: The MacPorts package to install from
#
checkinstalled() {
  local l_prog=$1
  local l_version="$2"
  local l_linuxpackage=$3
  local l_macospackage=$4
  os=`uname`
  color_msg $green "checking that $l_prog  is installed on os $os ..."
  which $l_prog
  if [ $? -eq 0 ]
  then
    $l_prog $l_version
  else
    case $os in
      # Mac OS
      Darwin) l_package=$l_macospackage;;
      *) l_package=$l_linuxpackage;;
    esac
    color_msg $blue "$l_prog is not available - shall i install it from $l_package y/n/a?"
    read x
    case $x in
      y)
        case $os in
          # Mac OS
          Darwin)
            color_msg $blue "installing $l_prog from MacPorts package $l_macospackage"
            sudo port install $l_macospackage
          ;;
          # e.g. Ubuntu/Fedora/Debian/Suse
          Linux)
            color_msg $blue "installing $l_prog from apt-package $l_linuxpackage"
            sudo apt-get install -y $l_linuxpackage
          ;;
          # git bash (Windows)
          MINGW32_NT-6.1)
            error "$l_prog ist not installed"
          ;;
          *)
            error "unknown operating system $os"
        esac;;
      a)
       color_msg $red "aborting ..."
       exit 1;;
    esac
  fi
}

#
# get the realpath for the given path
#
getrealpath() {
   local l_path="$1"
   case $(uname) in
      Darwin)
        echo $(pwd)/$l_path
        ;;
      *)
        realpath $l_path
        ;;
   esac
}

# install prerequisites
install() {
  local l_pyversion="$1"
  local l_pyversionNumeric=$(echo $1 | sed "s/\.//g")
  color_msg $blue "checking prerequisites ..."
  checkinstalled java "-version" "openjdk-8-jre" "openjdk8"
  checkinstalled $python "--version" "python${l_pyversion}" "python${l_pyversionNumeric}"
  checkinstalled $pip "--version" "python${l_pyversion}-pip" "py{$l_pyversionNumeric}-pip"
  checkinstalled pytest "--version" "python-pytest" "py${l_pyversionNumeric}-pytest"

  for d in $gsd $gcd
  do
    if [ ! -d $d ]
    then
      zip=$d-bin.zip
      if [ ! -f $zip ]
      then
        color_msg $blue "downloading $zip"
        curl -s $mirror/$zip -o $zip
      else
        color_msg $green "$zip already downloaded"
      fi
      color_msg $blue "unzipping $zip"
      unzip -q $zip
    else
      color_msg $green "$d already unzipped"
    fi
  done
  color_msg $blue "installing needed python modules"
  pip install .
}

# commandline option
while [  "$1" != ""  ]
do
  option=$1
  shift
  case $option in
    -i|--install)
      install $pyversion;;
    -s|--server)
      #conf=$(realpath $gsd/conf/gremlin-server-modern-py.yaml)
      conf=$(getrealpath $gsd/conf/gremlin-server-modern.yaml)
      color_msg $blue "starting gremlin-server ... using $conf"
      $gsd/bin/gremlin-server.sh $conf
      ;;
    -sd|--server_docker)
      example_dir=$HOME/.gremlin-examples
      if [ ! -d $example_dir ]
      then
        color_msg $blue "create example directory $example_dir ..."
        mkdir -p $example_dir
      else
        color_msg $green "example directory $example_dir already exists ..."
      fi

      color_msg $blue "starting gremlin-server via Docker ..."
      #  export GREMLIN_YAML=/opt/gremlin-server/conf/gremlin-server.yaml
      docker run --name gremlin-server -v $example_dir:/opt/gremlin-server/data/examples -p 8182:8182 tinkerpop/gremlin-server:$version conf/gremlin-server.yaml
      #
      ;;
    -n|--neo4j)
      plugin=neo4j-gremlin
      if [ ! -d $gsd/ext/$plugin ]
      then
        color_msg $blue "installing plugin $plugin"
        $gsd/bin/gremlin-server.sh install org.apache.tinkerpop $plugin $version
      else
        color_msg $green "$plugin plugin already installed"
      fi
      color_msg $blue "starting neo4j gremlin-server ..."
      conf=$(realpath $gsd/conf/gremlin-server-neo4j.yaml)
      $gsd/bin/gremlin-server.sh $conf
      ;;
    -b|--bash)
      color_msg $blue "starting docker bash"
      docker exec -it  gremlin-server /bin/bash
      ;;
    -c|--console)
      color_msg $blue "starting gremlin-console ..."
      $gcd/bin/gremlin.sh
      ;;
    -cd|--console_docker)
      color_msg $blue "starting gremlin-console via Docker..."
      docker run -it tinkerpop/gremlin-console:$version --name gremlin-console
      ;;
    -p|--python)
      color_msg $blue "starting python test code"
      $python -m unittest tests/test_tutorial.py
      ;;
    -pv|--pythonversion)
      shift
      pyversion="$1"
      color_msg $blue "using python version $pyversion"
      ;;
    -v|--version)
      color_msg $blue "apache-tinkerpop-gremlin version $version"
      ;;
    -t|--test)
      $python -m pytest -p no:warnings -s
      ;;
    -h|--help)
      usage;;
    *)
      error "invalid option $option"
      usage
  esac
done
