#!/bin/sh

ru_env=$(which radical-utils-env.sh)
if test -z '$ru_env'
then
    echo "$0 needs radical.utils installed"
    exit 1
fi

. radical-utils-env.sh

set -e  # exit on all errors

SCRIPT="$0"
PREFIX=         # full path or virtenv name
VERSION=        # python version (e.g., 2.7, 3.6, etc.)
                # NOTE: for virtualenv corresponding version should be installed
MODULES=        # alternative list of pre-installed modules/packages
DEFAULTS=       # install default modules
ENV_SETUP=''    # command(s) to set up starting environment

pre_exec(){
    echo "=== pre exec: $*"
    $*
    echo "=== pre exec done"
}

while getopts "e:p:P:v:m:d" OPTION; do
    case $OPTION in
        e)  ENV_SETUP="$OPTARG" ;;
        p)  PREFIX="$OPTARG"    ;;
        P)  pre_exec "$OPTARG"  ;;
        v)  VERSION="$OPTARG"   ;;
        m)  MODULES="$OPTARG"   ;;
        d)  DEFAULTS=True       ;;
        *)  echo "Unknown option: '$OPTION'='$OPTARG'"
            return 1;;
    esac
done

test -z "$VERSION" && VERSION='3.8'
test -z "$PREFIX"  && echo "no prefix" && exit

unset PYTHONPATH
echo "[$0 $*]"

# move from comma separated to space separated module list
MODULES=$(echo "$MODULES" | sed -e 's/,/ /g')

if ! test -z "$DEFAULTS"
then
    # by default, install all RCT dependencies
    MODULES="$MODULES apache-libcloud chardet colorama idna msgpack"
    MODULES="$MODULES msgpack-python netifaces ntplib parse pymongo<4"
    MODULES="$MODULES pyzmq regex requests setproctitle urllib3"
fi

if ! test -z "$ENV_SETUP"
then
    echo "runing env setup: $ENV_SETUP"
    $ENV_SETUP
fi

# ------------------------------------------------------------------------------
#
help(){

    err="$1"
    ret=0

    if ! test -z "$err"
    then
        ret=1
        printf "\n    ERROR: $err\n"
    fi

    cat <<EOT

    usage: $0 [-d] -p <path> [-v <version>] [-m <modules>] [-e env_setup]

    This script creates a virtualenv at the given target path.  That
    virtualenv should be suitable to be used as static VE for a radical.pilot
    target resource, and can be specified in a resource configuration for RP.

    version  :  python version to use
    modules  :  comma separated list of modules to install
    env_setup:  command string to execute for environment setup

    -d: install default RCT dependencies into the target virtualenv

EOT
    exit $ret
}


# ------------------------------------------------------------------------------
#
progress(){
  while read X
  do
  # echo $X
    echo -n .
  done
  echo
}


# ------------------------------------------------------------------------------
#
test    "$PREFIX" = "-h" && help
test -z "$PREFIX"        && help "missing target"
test -e "$PREFIX"        && help "target '$PREFIX' exists"

# Ensure we install in an absolute path -- pip seems to like that better...
case $PREFIX in
    /*)
        ;;
    *)
        PREFIX="$(pwd)/$PREFIX"
        ;;
esac


echo "create  rct ve [$PREFIX]"
PYTHON=python3

if test -z "$VERSION"
then
    VERSION=$($PYTHON -V | cut -f 2 -d ' ' | cut -f 1,2 -d '.')
fi

# create the ve, install bare necessities
mkdir -p "$PREFIX"
cd $PREFIX
PREFIX=`pwd -P`


# use conda if available
if ! test -z "$CONDA_DEFAULT_ENV"
then
    # conda developers did not think this through... :-(
    CONDA="$(which conda 2>/dev/null | head -n 1)"
    test -z "$CONDA" && CONDA="$_CONDA_EXE"
    test -z "$CONDA" && CONDA="$CONDA_EXE"
    if test -z "$CONDA"
    then
        echo "conda is not functional"
        exit 1
    fi
    echo -n "install conda virtualenv "
    "$CONDA" install -y virtualenv 2>&1 | progress || exit 1
fi


# TODO: find out why this hangs in GH ci
# VIRTENV_CMD="$(which virtualenv 2>/dev/null)"
VIRTENV_CMD="$PYTHON -m venv"

if test -z "$VIRTENV_CMD"
then
    echo -n "install private virtualenv "
    VIRTENV_VER=20.0.27
    VIRTENV_TGZ="$VIRTENV_VER.tar.gz"
    VIRTENV_TGZ_URL="https://github.com/pypa/virtualenv/archive/$VIRTENV_TGZ"

    curl -k -L -O "$VIRTENV_TGZ_URL" 2>&1  | progress
    tar zxf "$VIRTENV_TGZ"
    VIRTENV_CMD="$PYTHON $VIRTENV_VER/virtualenv.py"
fi

echo -n "create  virtualenv "
echo stdbuf -oL $VIRTENV_CMD "$PREFIX"
stdbuf -oL $VIRTENV_CMD "$PREFIX" | progress

. "$PREFIX"/bin/activate

env | sort > env.clean5

echo -n "update  setuptools pip wheel"
pip install --no-cache-dir --upgrade setuptools pip wheel| progress || exit 1

for mod in $MODULES
do
    echo -n "install $mod "
    stdbuf -oL pip install -I --no-cache-dir --upgrade "'$mod'" || exit 1
done

env_dump -t "$PREFIX.env"

# print the ve information and stack versions for verification
echo
echo "---------------------------------------------------------------------"
echo
echo "ENV       : $PREFIX.env"
echo "SCRIPT    : $SCRIPT"
echo "PREFIX    : $PREFIX"
echo "VERSION   : $VERSION"
echo "MODULES   : $MODULES"
echo "DEFAULTS  : $DEFAULTS"
echo "PYTHON    : $(which $PYTHON) ($($PYTHON -V))"
echo "PYTHONPATH: $PYTHONPATH"
echo "RCT_STACK : $(radical-stack || true)"
echo
echo "---------------------------------------------------------------------"
echo

echo ==================

