#!/bin/bash

###############################################################################
# Copyright (C) 2017 by gempa GmbH                                            #
#                                                                             #
# All Rights Reserved.                                                        #
#                                                                             #
# NOTICE: All information contained herein is, and remains                    #
# the property of gempa GmbH and its suppliers, if any. The intellectual      #
# and technical concepts contained herein are proprietary to gempa GmbH       #
# and its suppliers.                                                          #
# Dissemination of this information or reproduction of this material          #
# is strictly forbidden unless prior written permission is obtained           #
# from gempa GmbH.                                                            #
#                                                                             #
# Author: Ralph Henneberger, Stephan Herrnkind                                #
# Email: ralix@gempa.de, herrnkind@gempa.de                                   #
###############################################################################

file_path="$(readlink -f "${0}")"
base_dir="$(dirname "${file_path}")"
venv_dir="${base_dir}/var/venv"
venv_python="${venv_dir}/bin/python"
venv_pip="${venv_dir}/bin/pip"
gsm_bin="$0"

# Detect whether the user passed an explicit config (-c/--config). Scanning
# the argument array is robust; a substring match on "$*" would misfire on
# paths that merely contain "-c ".
have_config=0
for arg in "$@"; do
	if [ "$arg" = "-c" ] || [ "$arg" = "--config" ]; then
		have_config=1
		break
	fi
done

# Run gsm.py, preserving argument quoting via "$@".
function run_gsm() {
	if [ "$have_config" -eq 1 ]; then
		"${venv_python}" bin/gsm.py "$@"
	else
		"${venv_python}" bin/gsm.py -C "$gsm_bin" "$@"
	fi
}


# Print error message and exit with code 1
function error() {
	>&2 echo "$1"
	exit 1
}

# Install dependencies into existing venv
function install_deps() {
	echo "Installing Python dependencies"
	pip_log="var/log/pip.log"
	echo "---------------------------------
$(date -Iseconds)
---------------------------------" >>$pip_log
	"${venv_pip}" install --upgrade pip >>$pip_log|| error "Could not upgrade pip, check $pip_log for errors"
	"${venv_pip}" install -r share/venv/requirements.txt >>$pip_log || error "Could not install dependencies, check $pip_log for errors"
}

# Search for suitable Python version
function detect_python_bin() {
	>&2 echo "Searching Python executable"
	python_bin=$(which python3 2>/dev/null) || error "Python3 executable not found"
	minor_version=$(${python_bin} -c "import sys; print(sys.version_info.minor)") || error "Could not detect Python minor version"
	test ${minor_version} -ge 9 && echo "$python_bin" && return 0

	for minor in {15..9}; do
		binary="python3.${minor}"
		#>&2 echo "  .. searching for $binary"
		python_bin=$(which "${binary}" 2>/dev/null) || continue

		echo "$python_bin" && return 0
	done

	error "GSM requires at least Python 3.9. You have 3.${minor_version}.

On RHEL 8 you may install install Python 3.9 as follows

  su -
  dnf install python39"
}

# Create virtual environment
function create_venv() {
    python_bin=$(detect_python_bin)

    echo "Using ${python_bin}"
    echo "Creating Python virtual environment: ${venv_dir}"

    if ! "${python_bin}" -m venv "${venv_dir}"; then
        echo "Could not create Python virtual environment"
        if [ -d "${venv_dir}" ]; then
            echo "Deleting incomplete virtual environment: ${venv_dir}"
            rm -rf "${venv_dir}"
        fi
        exit 1
    fi
}

# Change working dir to GSM installation path
cd "${base_dir}" || error "Could not change directory to ${base_dir}"

mkdir -p var/log || error "Could not create log directory"

# Create venv if directory is missing
if [ ! -d "${venv_dir}" ]; then
	create_venv
	install_deps
fi

# Launch GSM and evaluate return code
run_gsm "$@"
ret=$?

# Restart command after GSM update or in case not all requirements
# are fulfilled
if [ $ret -eq 10 ]; then
	install_deps
	run_gsm "$@"
	ret=$?
fi

exit $ret

