#!/usr/bin/env bash
function help(){
echo "Usage: $0 [-R/-t]"
echo "
Available options:
    -R   remove (uninstall) pyradio
    -t   Use this terminal for Desktop file (linux only)

If no option is used, will build using Python 3
and will install in your HOME directory

Checking python availability:"

            for n in 2 3 "";do
                echo -n "  python${n}"
                [ -z "$n" ] && echo -n " "
                echo -n "   ...   "
                python${n} --version 2>/dev/null 1>&2 && {
                    python${n} --version
                } || echo not found
            done
            echo
}

function check_pipx() {
    # Test 1: python -m pipx
    local pipx_test=$(python"${TO_PYTHON}" -m pipx --version 2>/dev/null)
    if [ -n "$pipx_test" ]; then
        echo "python${TO_PYTHON} -m pipx"
        return 0
    fi

    # Test 2: standalone pipx
    pipx_test=$(pipx --version 2>/dev/null)
    if [ -n "$pipx_test" ]; then
        echo "pipx"
        return 0
    fi

    # Test 3: absolute  path (usuall location on macOS)
    pipx_test=$(/usr/local/bin/pipx --version 2>/dev/null)
    if [ -n "$pipx_test" ]; then
        echo "/usr/local/bin/pipx"
        return 0
    fi

    # Test 4: other possible locations
    local potential_paths=(
        "/opt/homebrew/bin/pipx"
        "/usr/bin/pipx" 
        "$HOME/.local/bin/pipx"
    )
    
    for path in "${potential_paths[@]}"; do
        if [ -x "$path" ]; then
            pipx_test=$("$path" --version 2>/dev/null)
            if [ -n "$pipx_test" ]; then
                echo "$path"
                return 0
            fi
        fi
    done

    return 1
}

function pipx_error(){
cat <<END
The installation has failed!!!
Please report this at https://github.com/coderholic/pyradio/issues

END
exit 1
}

function pip_error(){
cat <<END
Your installation is missing python's package manager (pip)
Please install it and try again...

END
exit 1
}

function find_paths(){
local APATH
python devel/site.py 2>/dev/null
python3 devel/site.py 2>/dev/null
APATH=$(python -m site --user-site 2>/dev/null) && echo "$APATH"
APATH=$(python3 -m site --user-site 2>/dev/null) && echo "$APATH"
}

function remove_paths(){
echo "Looking for python installed files..."
find_paths | sort -u > /tmp/pyradio-uninstall.$$
while read line;do
    [ -d "$line" ] && {
    sudo find "$line" -type d -name "pyradio*egg" >> /tmp/pyradio-delete.$$
    }
done < /tmp/pyradio-uninstall.$$
while read line;do
    [ -d "$line" ] && {
        echo -n "** Removing \"$(basename $line)\" ... "
        sudo rm -rf "$line"
        echo done
    }
done < /tmp/pyradio-delete.$$
rm -f /tmp/pyradio-uninstall.$$ /tmp/pyradio-delete.$$ 2>/dev/null
}

function remove_pip_sudo_install(){
    sudo python -m pip uninstall -y pyradio 2>/dev/null 1>&2 || pip_error
    sudo python2 -m pip uninstall -y pyradio 2>/dev/null 1>&2
    sudo python3 -m pip uninstall -y pyradio 2>/dev/null 1>&2
}

function uninstall(){
    echo 'Uninstalling PyRadio'
    echo -n '  ** Removing python files ... '
    echo -n "Looking for pipx ... "
    PIPX_CMD=$(check_pipx)
    if [ -n "$PIPX_CMD" ]; then
        PIPX=1
        PIPX_VERSION=$($PIPX_CMD --version 2>/dev/null)
        echo "$PIPX_VERSION (found via: $PIPX_CMD)"
    else
        echo "not found"
    fi
    if [ -z "${PIPX}" ]
    then
        python -m pip uninstall -y pyradio 2>/dev/null 1>&2
        python2 -m pip uninstall -y pyradio 2>/dev/null 1>&2
        python3 -m pip uninstall -y pyradio 2>/dev/null 1>&2
    else
        $PIPX_CMD uninstall pyradio 2>/dev/null 1>&2
    fi
    echo 'done'
    echo -n '  ** Removing help files ... '
    if [ -d ~/.local/share/doc/pyradio ]
    then
        rm -rf ~/.local/share/doc/pyradio 2>/dev/null
    else
        rm -rf ~/.local/local/share/doc/pyradio 2>/dev/null
    fi
    rm -f ~/.local/share/man/man1/pyradio*gz 2>/dev/null
    rm -f ~/.local/share/applications/pyradio.desktop 2>/dev/null
    echo 'done'
    if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ]
    then
        # delete link on mac
        [ -h ~/bin/pyradio ] && {
            echo -n '  ** Removing link to executable ... '
            rm ~/bin/pyradio 2>/dev/null
            echo 'done'
        }
    fi
    rm "${DATA_DIR}"/INSTALLATION_TYPE 2>/dev/null
    if [ $(uname -s) == "Darwin" ] || [ $(uname -s) == "darwin" ]
    then
        [ -d /Applications/PyRadio.app ] && {
            echo
            rm -rf /Applications/PyRadio.app 2>/dev/null || true
            if ! rm -rf /Applications/PyRadio.app 2>/dev/null; then
                echo
                echo -n "Please type your "
                sudo rm -rf /Applications/PyRadio.app 2>/dev/null
                echo
            fi
        }
    fi
    echo "PyRadio successfully uninstalled"
}

function uninstall_sudo(){
    local user
    [ -z "$1" ] && {
        user=$(which pyradio 2>/dev/null) || {
            echo "PyRadio is not installed..."
            exit
        }
    }
    sudo echo 'Uninstalling PyRadio'
    echo -n '  ** Removing executable ... '
    sudo rm -f `which pyradio 2>/dev/null` 2>/dev/null
    sudo rm -f `which pyradio-client 2>/dev/null` 2>/dev/null
    if [ -d /usr/share/doc/pyradio ]
    then
        sudo rm -rf /usr/share/doc/pyradio 2>/dev/null
    else
        sudo rm -rf /usr/local/share/doc/pyradio 2>/dev/null
    fi
    echo done
    echo -n '  ** Removing help files ... '
    sudo rm -f /usr/share/man/man1/pyradio.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio.1.gz 2>/dev/null
    sudo rm -f /usr/share/man/man1/pyradio_rb.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio_rb.1.gz 2>/dev/null
    sudo rm -f /usr/share/man/man1/pyradio_buf.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio_buf.1.gz 2>/dev/null
    sudo rm -f /usr/share/man/man1/pyradio_server.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio_server.1.gz 2>/dev/null
    sudo rm -f /usr/share/man/man1/pyradio-client.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio-client.1.gz 2>/dev/null
    echo done
#set -x
    remove_paths
    remove_pip_sudo_install
    if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ]
    then
        # delete link on mac
        [ -h ~/bin/pyradio ] && rm ~/bin/pyradio 2>/dev/null
    fi
    echo "PyRadio successfully uninstalled"
}

function get_cur_version(){
    cur_version=$(grep 'version_info = ' pyradio/__init__.py | sed 's/version_info = (//;s/, /./g;s/)//')
    cur_state=$(grep 'app_state = ' pyradio/__init__.py | sed "s/app_state = //;s/'//g")
    [[ -z "$cur_state" ]] || cur_version="$cur_version"-"$cur_state"
    #echo "$cur_version"
}

function do_dev(){
    if [ -z "${NO_DEV}" ]
    then
        [ -z "$DEVEL" ] && {
            rm pyradio/config.pydev 2>/dev/null
            return
        }
        sed -i "s/git_description = ''/git_description = '$DEVEL'/" pyradio/config.py
    fi
}

function do_undev(){
    if [ -e pyradio/config.pydev ]
    then
        mv pyradio/config.pydev pyradio/config.py
    fi
}

function do_exit(){
    # remove instasllation directory
    if [ ! -z "$REMOVE_DIR" ]
    then
        if [ "$REMOVE_DIR" = "$HOME/pyradio" ] || \
                [ "$REMOVE_DIR" = "$HOME/tmp-pyradio" ] || \
                [ "$REMOVE_DIR" = "/tmp/pyradio" ] || \
                [ "$REMOVE_DIR" = "/tmp/tmp-pyradio" ]
        then
            rm -fr "$REMOVE_DIR"
        fi
    fi
}

function check_installation_type(){
    if [ -z "$PIPX" ]
    then
        echo
        echo 'Error: Inconsistent installation type!'
        echo
        echo 'A previous pipx installation has been retected,'
        echo 'but pipx is not installed in your system anymore.'
        echo 'Please install pipx and try again!'
        exit 1
    fi
}

function create_installation_type_file(){
    mkdir -p "${DATA_DIR}" && \
        echo "$inst_type" > "${DATA_DIR}"/INSTALLATION_TYPE
    if (( $inst_type > 0 ))
    then
        OLD=$(find ~/.local/lib -type d -name "pyradio*" 2>/dev/null | grep -v pipx | grep -v venvs)
        if [ ! -z "$OLD" ]
        then
            msg="

The following [magenta]pyradio[/magenta] directories have been found:
[red]$OLD[/red]

They probably belong to an older non-pipx installation
and they [red]should be deleted[/red].
"
            python${TO_PYTHON} -c \
                'import sys; from rich import print; print(sys.argv[1])' \
                "${msg}"
        fi
    fi
}

function check_root(){
    if [ "$UID" = "0" ] || [ "$USER" = "root" ]
    then
        echo "Error: You must not run this script as root"
        echo
        exit 1
    fi
}

function get_data_dir(){
    SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
    CFG_FILE=$(dirname $"$SCRIPT_DIR")"/pyradio/config"
    if [ -e "$CFG_FILE" ]
    then
        XDG="$(sed 's/[A-Z]/\l&/' "$CFG_FILE" | grep 'xdg_compliant = true')"
    fi
    if [ -z "$XDG" ]
    then
        DATA_DIR=~/.config/pyradio/data
    else
        DATA_DIR="$XDG_DATA_HOME"
        [ -z "$DATA_DIR" ] && DATA_DIR=~/.local/share/pyradio
    fi
    mkdir -p "$DATA_DIR" 2>/dev/null
}

check_root
get_data_dir
rm -rf build pyradio.egg-info 2>/dev/null
TO_PYTHON=3
[[ $(python --version 2>/dev/null) == *" 3."* ]] && TO_PYTHON=''
TO_PYTHON_FROM_X=''
NO_DEV=''
while [[ $# -gt 0 ]]
do
    key="$1"
    case $key in
        -h|--help)
            help
            exit
            ;;
        -t)
            shift
            if [ -z "$1" ]
            then
                echo "Error: No terminal specified..."
                echo
                exit 1
            fi
            REQ_TERMINAL="$1"
            shift
            ;;
        --warning)
            # macos only; execute "put pyradio in PATH" and
            # display warning (not error) if pyradio executable
            # is not found
            #
            # DO NOT USE IT on any other circumstance
            #
            WARNING=1
            shift
            ;;
        --isolate|-i)
            PIPX_ISOLATE=1
            shift
            ;;
        -R)
            uninstall
            exit
            ;;
        2)
            echo
            echo
            echo "Error: PyRadio does not support python 2 any more."
            echo "Please install python 3 and try again."
            exit 1
            shift
            ;;
        -x)
            #
            # Hidden parameter; to be used by
            #     pyradio -U, -R
            # command line parameters
            #
            # DO NOT USE IT on any other circumstance
            #
            REMOVE_DIR=$(dirname "$PWD")
            shift
            TO_PYTHON=${1/python/}
            if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ]
            then
                TO_PYTHON=3
            fi
            TO_PYTHON_FROM_X=1
            shift
            ;;
        -n)
            NO_DEV=1
            shift
            ;;
        *)    # unknown option
            POSITIONAL+=("$1") # save it in an array for later
            shift # past argument
            ;;
    esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters

# check dependencies :)
for prog in sed ;do
    ${prog} --version 2>/dev/null 1>&2 || {
        if [ "${prog}" = "sed" ]
        then
            sed 's/a/b/' LICENSE > /dev/null ||{
                echo "Error: ${prog} not found."
                echo "       Please install it and try again."
                exit 1
            }
        else
                echo "Error: ${prog} not found."
                echo "       Please install it and try again."
                exit 1
        fi
    }
done

do_dev

#
# Use pipx by default, if installed
echo -n "Looking for pipx ... "
PIPX_CMD=$(check_pipx)
if [ -n "$PIPX_CMD" ]; then
    PIPX=1
    PIPX_VERSION=$($PIPX_CMD --version 2>/dev/null)
    echo "$PIPX_VERSION (found via: $PIPX_CMD)"
else
    echo "not found"
fi

if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ]
then
    [ -z "$PIPX" ] && {
        echo
        echo
        echo "Error: pipx not found."
        echo "       Please install pipx and try again"
        exit 1
    }
fi


if [ "${TO_PYTHON}" != "2" ];
then
    # Make an editable installation if
    #       ~/.pyradio-editable
    # exists
    test -e ~/.pyradio-editable && PIPX_EDITABLE="-e"

    inst_type=0
    if [ -e "${DATA_DIR}"/INSTALLATION_TYPE ]
    then
        # we have an update
        # read INSTALLATION_TYPE and identify installation file
        read inst_type < "${DATA_DIR}"/INSTALLATION_TYPE
        if [ ! -z "$inst_type" ]
        then
            if [ "$inst_type" = "1" ]
            then
                # pipx installation without isolation
                check_installation_type
            elif [ "$inst_type" = "2" ]
            then
                # pipx installation with isolation
                check_installation_type
                PIPX_ISOLATE=1
                [ -e "${DATA_DIR}"/DBUS-NEXT ] && {
                    echo -n "next" > "${DATA_DIR}"/DBUS
                    rm -f "${DATA_DIR}"/DBUS-NEXT
                }
                [ -e ~/.local/share/pyradio/DBUS-NEXT ] && {
                    echo -n "next" >~/.local/share/pyradio/DBUS
                    rm -f ~/.local/share/pyradio/DBUS-NEXT
                }
                [ -e "${DATA_DIR}"/DBUS ] && read -r DBUS < "${DATA_DIR}"/DBUS
                [ -e ~/.local/share/pyradio/DBUS ] && DBUS < ~/.local/share/pyradio/DBUS
                [ -z "$DBUS" ] || {
                    if [ "$DBUS" != "next" ] && [ "$DBUS" != "fast" ]
                    then
                        DBUS="fast"
                    fi
                }
            else
                # normal pip installation
                if [ ! -z "$PIPX" ]
                then
                    inst_type=1
                fi
            fi
        fi
    fi
fi

if [ -z "$PIPX" ]
then
    # Normanl, old style installation
    if [ -e requirements.txt ]
    then
        python"${TO_PYTHON}" -m pip install -r requirements.txt . || pip_error
    else
        python"${TO_PYTHON}" -m pip install . || pip_error
    fi
    [ -e setup.py.orig ] && cp setup.py.orig setup.py
else
    # pipx installation
    # MacOS will always perform a fully isolated installation
    if [ $(uname -s) == "Darwin" ] || [ $(uname -s) == "darwin" ]
    then
        PIPX_ISOLATE=1
    fi
    # fix toml file for python 3.8
    PY_VERSION=$(python${TO_PYTHON} -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
    if [ "$PY_VERSION" = "3.8" ]
    then
        echo "Patching pyproject.toml for Python 3.8"
        cp pyproject.toml pyproject.toml.BCK
        patch -p0 < pyproject-3.8.patch || {
            echo "Error applying the Python 3.8 patch
    patch -p0 < pyproject-3.8.patch
Please make sure patch is installed and try again
    "
    mv pyproject.toml.BCK pyproject.toml 
    exit 1
        }
    fi
    if [ -z "$PIPX_ISOLATE" ]
    then
        $PIPX_CMD install $PIPX_EDITABLE --system-site-packages --force . || pipx_error
        inst_type=1
    else
        $PIPX_CMD install $PIPX_EDITABLE --force . || pipx_error
        [ -z "$PIPX_EDITABLE" ] && {
            # fix pipx issue: Do not check if the package is a path in the current working directory #1778
            cd devel
            cat ../requirements_pipx.txt | sed -e 's/#.*//' | xargs $PIPX_CMD inject pyradio
            cd ..
            if [ $(uname -s) == "Darwin" ] || [ $(uname -s) == "darwin" ]
            then
                # fix pipx issue: Do not check if the package is a path in the current working directory #1778
                cd devel
                $PIPX_CMD inject pyradio pyobjc-core pyobjc-framework-Cocoa pyobjc-framework-MediaPlayer
                cd ..
                rm -rf /Applications/PyRadio.app 2>/dev/null || true
                if ! tar -xpzf devel/PyRadio_mac_app.tar.gz -C /Applications 2>/dev/null; then
                    echo
                    echo -n "Please type your "
                    sudo rm -rf /Applications/PyRadio.app 2>/dev/null || true
                    sudo tar -xpzf devel/PyRadio_mac_app.tar.gz -C /Applications || true
                    echo
                fi
                mdimport -r /Applications/PyRadio.app 2>/dev/null || true
                /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f /Applications/PyRadio.app 2>/dev/null || true
                killall Finder >/dev/null 2>&1 || true
            else
                # fix pipx issue: Do not check if the package is a path in the current working directory #1778
                cd devel
                [ -z "$DBUS" ] || $PIPX_CMD inject pyradio dbus-"${DBUS}"
                cd ..
            fi
        }
        inst_type=2
    fi
    [ -e  pyproject.toml.BCK ] && mv pyproject.toml.BCK pyproject.toml
fi

do_undev

if [ $? -eq 0 ]
then
    [ -z "${NO_DEV}" ] && [ -e pyradio/config.py.dev ] && mv pyradio/config.py.dev pyradio/config.py
    cd docs
    gzip -k pyradio.1
    gzip -k pyradio_rb.1
    gzip -k pyradio_buf.1
    gzip -k pyradio_rec.1
    gzip -k pyradio_server.1
    gzip -k pyradio-client.1
    mkdir -p ~/.local/share/man/man1 2>/dev/null
    mv -f pyradio.1.gz ~/.local/share/man/man1 2>/dev/null || mv -f pyradio.1.gz ~/.local/local/share/man/man1
    mv -f pyradio_rb.1.gz ~/.local/share/man/man1 2>/dev/null || mv -f pyradio_rb.1.gz ~/.local/local/share/man/man1
    mv -f pyradio_server.1.gz ~/.local/share/man/man1 2>/dev/null || mv -f pyradio_server.1.gz ~/.local/local/share/man/man1
    mv -f pyradio-client.1.gz ~/.local/share/man/man1 2>/dev/null || mv -f pyradio-client.1.gz ~/.local/local/share/man/man1
    mv -f pyradio_rec.1.gz ~/.local/share/man/man1 2>/dev/null || mv -f pyradio_rec.1.gz ~/.local/local/share/man/man1
    mv -f pyradio_buf.1.gz ~/.local/share/man/man1 2>/dev/null || mv -f pyradio_buf.1.gz ~/.local/local/share/man/man1
    DOC=~/.local/share/doc/pyradio
    mkdir -p "$DOC" 2>/dev/null
    if [ ! -d "$DOC" ]
    then
        # Mac OS SIP protects /usr
        DOC=~/.local/local/share/doc/pyradio
        mkdir "$DOC"
    fi
    for n in *.md *.html
    do
        cp "$n" "$DOC"
    done
    cd ..
    # copy LICENSE
    mkdir -p ~/.local/share/licenses 2>/dev/null
    if [ "$DOC" = "~/.local/share/doc/pyradio" ]
    then
        mkdir -p ~/.local/share/licenses/pyradio 2>/dev/null
        cp LICENSE ~/.local/share/licenses/pyradio
    else
        cp LICENSE "$DOC"
    fi
    if [ $(uname -s) != "Darwin" ] && [ $(uname -s) != "darwin" ]
    then
        if [ ! -z "$(grep 'distro = None' pyradio/config)" ]
        then
            if [ ! -e ~/.local/share/applications/pyradio.desktop ]
            then
                mkdir -p ~/.local/share/applications/ 2>/dev/null
                cp devel/pyradio.desktop ~/.local/share/applications/pyradio.desktop
            fi
            chmod +x ./devel/fix_pyradio_desktop_file
            if [ -z "${REQ_TERMINAL}" ]
            then
                ./devel/fix_pyradio_desktop_file -i
            else
                ./devel/fix_pyradio_desktop_file -i -t "${REQ_TERMINAL}"
            fi
        fi
    fi
    mkdir -p "${DATA_DIR}"
    cp devel/pyradio.png "${DATA_DIR}"
    cp devel/cover.png "${DATA_DIR}"
    [ -z $PIPX  ] || create_installation_type_file
else
    do_exit
    exit 1
fi

do_exit
exit 0
