#!/usr/bin/env -S bash --norc

# Copyright (C) 2025-2026 Dmitry Messerman
# SPDX-License-Identifier: GPL-3.0

script_path=$(dirname "$(realpath "$0")")
script_name=$(basename "$(realpath "$0")")
package=pyoptiwize
version=python3.12
wheel=pyoptiwize

usage() {
    echo "$script_name [[-h|--help] | [-clean] | [-w|--from_wheel] [-r|--force_reinstall] [-p|--python_version <version>] [-t|--testpypi]"
    echo "                                   -h --help:             display this help message"
    echo "                                   -clean:                clean all workareas $PWD/venv_31*"
    echo "                                   -w --from_wheel:       install $package from wheel https://pypi.org/project/$wheel"
    echo "                                   -r --force_reinstall:  reinstall $package in existing workarea"
    echo "                                   -p --python_version:   use python<version>"
    echo "                                   -j --run_jupyter:      start jupyter notebook server"
    echo "                                   -t --testpypi:         use test.pypi.org for pyoptiwize installation"
    echo "Supported python versions:           python3.11 python3.12 python3.13"
    echo "Default installation:                download git repository from the GitHub and then install from the latest version"
    echo "Default python version:              python3.12"
    echo "Virtual enviroment root directory:   $PWD/venv_31[1|2|3]"
    echo ""
    exit 1
}

from_wheel=
reinstall=
run_jupyter=
testpypi=

while [[ $# -gt 0 ]]; do
    opt="$1"
    shift
    case "$opt" in
        -h|--help)
            usage
            ;;
        -clean)
            rm -rf venv* 2>/dev/null
            exit 0
            ;;
        -w|--from_wheel)
            from_wheel=1
            ;;
        -r|--force_reinstall)
            reinstall=1
            ;;
        -p|--python_version)
            version="$1"
            shift
            if [[ ! "$version" =~ ^python3\.1[1-3]$ ]]; then
                echo -e "\nERROR: only python versions python3.11, python3.12 and python3.13 are supported\n"
                exit 1
            fi
            ;;
        -j|--jupyter)
            run_jupyter=1
            ;;
        -t|--testpypi)
            testpypi=1
            requests_package_dir=/tmp/${USER}_$$_requests/dist-packages
            rm -rf $requests_package_dir
            pip install requests --target $requests_package_dir
            test_version=$(env PYTHONPATH=$requests_package_dir $script_path/pyoptiwize_versions.py -atl)
            ;;
        *)
            echo -e "\nERROR: switch $opt is not supported\n"
            usage
            ;;
    esac
done

xset q >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
    echo -e "\nWARINING: GUI is not available"
    echo "Opening virtual display"
    "$script_path/open_virtual_display"
    if [[ $? -ne 0 ]]; then
        echo -e "\nERROR: failed to open virtual display. Exiting ...\n"
        exit 1
    fi
    export DISPLAY=:99
fi

version_digits=$(echo "$version" | tr -d 'a-z.')
if [[ -n "$run_jupyter" ]]; then
    log="$PWD/${script_name}_${version_digits}_run_jupyter.log"
else
    log="$PWD/${script_name}_${version_digits}.log"
fi
venv_root="venv_${version_digits}"

if [[ ! -f "$venv_root/bin/activate" ]]; then
    echo "Establishing python virtual environment in $PWD/${venv_root} directory"
    "${version}" -m venv "$venv_root"
    source "${venv_root}/bin/activate"
else
    echo "Virtual environment in $PWD/${venv_root} directory already exists"
    if [[ -n "$VIRTUAL_ENV" ]]; then
        echo "venv has been activated already"
    else
        echo "Activating virtual environment"
        source "${venv_root}/bin/activate"
    fi
fi

pip show -q "${package}"
package_status=$?

extra_status=0
if [[ -n "$run_jupyter" ]]; then
    pip show -q notebook
    extra_status=$?
else
    for test_package in pytest pytest-forked pytest-mock; do
        pip show -q "$test_package"
        (( extra_status += $? ))
    done
fi

if [[ $package_status -ne 0 || $extra_status -ne 0 || -n "$reinstall" ]]; then
    if [[ -n "$reinstall" ]]; then
        echo "Reinstalling $package ..."
        echo Y | pip uninstall $package
    else
        echo "Installing $package ..."
    fi
    if [[ -n "$from_wheel" ]]; then
        echo "From wheel: $wheel"
        if [[ -n "$run_jupyter" ]]; then
            if [[ -n "$testpypi" ]]; then
                pip install -i https://test.pypi.org/simple --extra-index-url https://pypi.org/simple  "${wheel}[notebook]==$test_version"
            else
                pip install "${wheel}[notebook]"
            fi
        else
            if [[ -n "$testpypi" ]]; then
                pip install -i https://test.pypi.org/simple --extra-index-url https://pypi.org/simple  "${wheel}[test]==$test_version"
            else
                pip install "${wheel}[test]"
            fi
        fi
    else
        repo="/tmp/${package}_repo_$$"
        rm -rf "$repo" 2>/dev/null
        git clone https://git@github.com/mdmitry1/optimization-tutorial "$repo"
        if [[ -n "$run_jupyter" ]]; then
            pip install "${repo}[notebook]"
        else
            pip install "${repo}[test]"
        fi
    fi
else
    echo "$package has been already installed, $(pip show -V "$package" | grep Version)"
fi

rundir="/tmp/optimization_tutorial_${USER}_$$"
echo "Run directory: $rundir" 2>&1 | tee "$log"
rm -rf "$rundir" 2>/dev/null
mkdir -p "$rundir"
cd "$rundir"

python_path=$(which python)
venv_path=$(dirname "$(dirname "$python_path")")
echo "$venv_path"

rm -rf "${venv_path}/lib/${version}/site-packages/"*mathsat* 2>/dev/null
cp -p /usr/local/lib/${version}/dist-packages/*mathsat* "${venv_path}/lib/${version}/site-packages"
rm -rf "${venv_path}/lib/${version}/site-packages/z3" 2>/dev/null
cp -rp /usr/lib/python3/dist-packages/z3 "${venv_path}/lib/${version}/site-packages"
cp -rp "${venv_path}/lib/${version}/site-packages/${package}" .

if [[ -n "$run_jupyter" ]]; then
    cd "${package}/examples"
    cmd="env PYTHONDONTWRITEBYTECODE=1 jupyter-notebook --ip 0.0.0.0"
    if [[ -f /.dockerenv ]]; then
        cmd="$cmd --no-browser --port=8888 --allow-root"
    fi
    echo "$cmd" 2>&1 | tee -a "$log"
    eval "$cmd" 2>&1 | tee -a "$log"
else
    cmd="env PYTHONDONTWRITEBYTECODE=1 pytest -v --forked -m forked $PWD/${package}/examples"
    echo "$cmd" 2>&1 | tee -a "$log"
    eval "$cmd" 2>&1 | tee -a "$log"
    cmd="env PYTHONDONTWRITEBYTECODE=1 pytest -v -s -m 'not forked' $PWD/${package}/examples"
    echo "$cmd" | tr "'" '"' 2>&1 | tee -a "$log"
    eval "$cmd" 2>&1 | tee -a "$log"
fi

exit $?
