#!/bin/bash -x

# Default Tempest commit:
# SHA 3c7eebaaf35c9e8a3f00c76cd1741457bdec9fab (April 2023)
CHECKOUT_POINT=3c7eebaaf35c9e8a3f00c76cd1741457bdec9fab
PY_VERSION="3.8.10"
UPPER_CONSTRAINTS_FILE="https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt"
LOCAL_INTERPRETER=false

# Prints help
function usage {
    set +x
    SCRIPT_NAME="basename ${BASH_SOURCE[0]}"
    echo "Usage: ${SCRIPT_NAME} [OPTION]..."
    echo "Setup RefStack client with test environment"
    echo ""
    echo "  -h  Print this usage message"
    echo "  -c  Tempest test runner commit. You can specify SHA or branch here"
    echo "      If no commit or tag is specified, tempest will be install from commit"
    echo "  -p  [ 3 | 3.X.X ] - Uses python 3.8.10 (if -p 3)"
    echo "      or given specific version (3.8 and higher, if -p 3.X.X). Default to python 3.8.10"
    echo "  -q  Run quietly. If .tempest folder exists, refstack-client is considered as installed"
    echo "  -s  Use python-tempestconf from the given source (path), used when running f.e. in Zuul"
    echo "  -t  Tempest test runner tag. You can specify tag here"
    echo "  -l  Force the installation of python version specified by -p (default 3.8.10) into"
    echo "      the ./localpython file. If parameter -l is false and version of python specified by"
    echo "      parameter -p is installed in the enviroment, script will use this interpreter."
    echo "      ${CHECKOUT_POINT}"
    exit 1
}

# Check that parameter is a valid tag in tempest repository
function check_tag {
        tags="$(git tag)"
        for tag in ${tags}; do
                [[ "${tag}" == "$1" ]] && return 0;
        done
        return 1
}

# By default tempest uses commit ${CHECKOUT_POINT}

while getopts c:p:t:qs:hl FLAG; do
    case ${FLAG} in
        c)
            CHECKOUT_POINT=${OPTARG}
            ;;
        p)
            if [ ${OPTARG} == '3' ]; then
                PY_VERSION=${PY_VERSION}
            elif [[ ${OPTARG} =~ ^3.([8-9]|[1-9][0-9]).([0-9]|[1-9][0-9])$ ]]; then
                # minimal version of python -> 3.8.0
                PY_VERSION=${OPTARG}
            else
                echo "Version of python-${OPTARG} no longer supported."
                usage
            fi
            ;;
        t)
            CHECKOUT_POINT="-q ${OPTARG}"
            ;;
        q)  #show help
            QUIET_MODE=true
            ;;
        s)  #show help
            TEMPESTCONF_SOURCE=${OPTARG}
            ;;
        h)  #show help
            usage
            ;;
        l)  # use local python interpreter
            LOCAL_INTERPRETER=true
            ;;
        \?) #unrecognized option - show help
            echo -e \\n"Option -$OPTARG not allowed."
            usage
            ;;
    esac
done

# Install git
WORKDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

TEMPEST_DIR=${REFSTACK_CLIENT_TEMPEST_DIR:-${WORKDIR}/.tempest}
if [ -z ${TEMPESTCONF_SOURCE} ]; then
    TEMPESTCONF_DIR=${REFSTACK_CLIENT_TEMPEST_DIR:-${WORKDIR}/.tempestconf}
else
    TEMPESTCONF_DIR=${TEMPESTCONF_SOURCE}
fi

# Checkout tempest on specified tag
if [ -d "${TEMPEST_DIR}" ]; then
    [ ${QUIET_MODE} ] && echo 'Looks like RefStack client is already installed' && exit 0
    while true; do
        read -p "Existing tempest installation found. We should remove it. All data from previous test runs will be deleted. Continue (y/n) ?" yn
        case ${yn} in
            [Yy]* ) rm -rf ${TEMPEST_DIR}; break;;
            [Nn]* ) exit 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
fi

if [ -n "$(command -v apt-get)" ]; then
    # For apt-get-based Linux distributions (Ubuntu, Debian)
    # If we run script in container we need sudo
    if [ ! -n "$(command -v sudo)" ]; then
        apt-get update || if [ $? -ne 0 ]; then exit 1; fi
        DEBIAN_FRONTEND=noninteractive apt-get -y install sudo
    else
        sudo apt-get update || if [ $? -ne 0 ]; then exit 1; fi
    fi
    sudo DEBIAN_FRONTEND=noninteractive apt-get -y install git
elif [ -n "$(command -v yum)" ]; then
    # For yum-based distributions (RHEL, Centos)
    # If we run script in container we need sudo
    DNF_COMMAND=yum
    if [ ! -f sudo ]; then
        ${DNF_COMMAND} -y install sudo
    fi
    sudo ${DNF_COMMAND} -y install git
elif [ -n "$(command -v dnf)" ]; then
    # For dnf-based distributions (Centos>8, Fedora)
    # If we run script in container we need sudo
    DNF_COMMAND=dnf
    if [ ! -f sudo ]; then
        ${DNF_COMMAND} -y install sudo
    fi
    sudo ${DNF_COMMAND} -y install git
elif [ -n "$(command -v zypper)" ]; then
    # For zypper-based distributions (openSUSE, SELS)
    # If we run script in container we need sudo
    if [ ! -f sudo ]; then
        zypper --gpg-auto-import-keys --non-interactive refresh
        zypper --non-interactive install sudo
    else
        sudo zypper --gpg-auto-import-keys --non-interactive refresh
    fi
    sudo zypper --non-interactive install git
else
    echo "Neither apt-get, nor yum, nor dnf, nor zypper found"
    exit 1
fi

if [ -z ${TEMPESTCONF_SOURCE} ]; then
    git clone https://opendev.org/openinfra/python-tempestconf.git ${TEMPESTCONF_DIR}
fi

git clone https://opendev.org/openstack/tempest.git ${TEMPEST_DIR}
cd ${TEMPEST_DIR}

git checkout $CHECKOUT_POINT || if [ $? -ne 0 ]; then exit 1; fi
cd ${WORKDIR}

# Setup binary requirements
if [ -n "$(command -v apt-get)" ]; then
    # For apt-get-based Linux distributions (Ubuntu, Debian)
    sudo DEBIAN_FRONTEND=noninteractive apt-get -y install curl wget tar unzip python3-dev build-essential libssl-dev libxslt-dev libsasl2-dev libffi-dev libbz2-dev libyaml-dev
elif [ -n "$DNF_COMMAND" -a -n "$(command -v ${DNF_COMMAND})" ]; then
    # For yum/dnf-based distributions (RHEL, Centos)
    sudo ${DNF_COMMAND} -y install curl wget tar unzip make gcc gcc-c++ libffi-devel libxml2-devel bzip2-devel libxslt-devel openssl-devel
    # python3 dependencies
    sudo ${DNF_COMMAND} -y install python3-devel
elif [ -n "$(command -v zypper)" ]; then
    # For zypper-based distributions (openSUSE, SELS)
    sudo zypper --non-interactive install curl wget tar unzip make python-devel.x86_64 gcc gcc-c++ libffi-devel libxml2-devel zlib-devel libxslt-devel libopenssl-devel python-xml libyaml-devel
else
    echo "Neither apt-get, nor yum, nor zypper found."
    exit 1
fi

# Build local python interpreter if needed
sub_pystr="python$(echo $PY_VERSION | grep -o '3.[0-9]\+')"
python_version=$($sub_pystr -V | cut -d " " -f 2)
if [ $python_version == $PY_VERSION ] && [ ${LOCAL_INTERPRETER} == false ]; then
    echo "Python $PY_VERSION found!"
    PYPATH="$sub_pystr"
else
    echo "Python $PY_VERSION not found. Building python ${PY_VERSION}..."
    mkdir ${WORKDIR}/.localpython
    mkdir ${WORKDIR}/.python_src
    cd ${WORKDIR}/.python_src
    wget http://www.python.org/ftp/python/${PY_VERSION}/Python-${PY_VERSION}.tgz
    tar zxvf Python-${PY_VERSION}.tgz
    cd Python-${PY_VERSION}

    ./configure --prefix=${WORKDIR}/.localpython --without-pymalloc
    make && make install
    cd ${WORKDIR}
    rm -rf ${WORKDIR}/.python_src
    PYPATH="${WORKDIR}/.localpython/bin/$sub_pystr"
fi

mkdir ${WORKDIR}/.localvirtualenv
VENV_VERSION='20.16.7'
$PYPATH -m pip install --target=${WORKDIR}/.localvirtualenv virtualenv==${VENV_VERSION}
export PYTHONPATH=$(realpath .localvirtualenv):$PYTHONPATH
VIRTUALENV=${WORKDIR}/.localvirtualenv/bin/virtualenv

# Option -S disable import of modules installed in python which are causing errors when creating virtual enviroment
$PYPATH -S $VIRTUALENV ${WORKDIR}/.venv --python="${PYPATH}"
$PYPATH -S $VIRTUALENV ${TEMPEST_DIR}/.venv --python="${PYPATH}"

${WORKDIR}/.venv/bin/python -m pip install -c ${UPPER_CONSTRAINTS_FILE} -e .
cd ${TEMPESTCONF_DIR}
${WORKDIR}/.venv/bin/python -m pip install -c ${UPPER_CONSTRAINTS_FILE} -e .
cd ..
${TEMPEST_DIR}/.venv/bin/python -m pip install -c ${UPPER_CONSTRAINTS_FILE} ${TEMPEST_DIR}

# Add additional packages to find more tests by tempest
# Note: Since there are no requirements in tempest-additional-requirements.txt by default,
# this line is commented out to prevent errors from being returned. Uncomment this line if
# there are requirements in tempest-additonal-requirements.txt.
# ${TEMPEST_DIR}/.venv/bin/pip install -c ${UPPER_CONSTRAINTS_FILE} -r ${WORKDIR}/tempest-additional-requirements.txt