#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2008-2024 Luis Falcón <falcon@gnuhealth.org>
# SPDX-FileCopyrightText: 2011-2024 GNU Solidario <health@gnusolidario.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later

#########################################################################
#   Hospital Management Information System (HMIS) component of the      #
#                       GNU Health project                              #
#                   https://www.gnuhealth.org                           #
#########################################################################
#                       gnuhealth-control                               #
#                The GNU Health control center                          #
#########################################################################

VERSION="4.4.0"

TRYTON_URL="https://downloads.tryton.org"
GNUHEALTH_URL="https://ftp.gnu.org/gnu/health"
TRANSLATE_URL="https://hosted.weblate.org"

TRYTON_MODULES="account account_invoice account_product company country \
    currency party product stock stock_lot purchase account_invoice_stock \
    stock_supply purchase_request"

UPDATE_DOWNLOAD_DIR="$HOME/.gnuhealth_update"

PATCH_TRYTON=0

TRYTON_PATCHES=""

BSDTAR="bsdtar"

usage()
{
    cat << EOF

This is GNU Health control center ${VERSION}

usage: `basename $0` command [options]

Command:

  version    : Show version
  backup     : Backup he gnuhealth kernel, attach dir and database
  update     : Download and install the patches
  instpydeps : Install or update the latest dependencies
  getlang    : Get and install / update the language pack code
  status     : Show environment and GNU Health Tryton server status

Options:

 --backdir  : destination directory for the backup file
 --dry-run  : Check, download and preview, but don't actually update process
 --database : database name to use with the backup command 

EOF
    exit 0
}

help()
{
    cat << EOF
    The GNU Health Control Center (gnuhealth-control) is the main tool for 
    administrative tasks of the GNU Health environment.

    It can perform backups and updates of the instance

    Updates
    -------

    When gnuhealth-control is invoked with the update command, 
    it will update GNU Health components within the same major number
    The following components will be checked and updated if necessary

        - Trytond : Tryton server version
        - GNU Health patchsets

    This will be valid for version with the same major and minor numbers, for example
    2.8.x will look for the latest tryton updates and GNU Health updates
    associated to that release.

    GNU Health Control is available for release 2.8 and newer.
    You can get the latest version of GNU Health update at GNU
    ftp://ftp.gnu.org/gnu/health


EOF
    usage
    exit 0
}

message()
{
    local UTC="$(date -u +'%Y-%m-%d %H:%M:%S')"

    case $1 in
      ERROR ) echo -e "\e[00;31m${UTC} [ERROR] $2\e[00m";;
      WARNING ) echo -e "\e[0;33m${UTC} [WARNING] $2\e[m" ;;
      INFO ) echo -e "\e[0;36m${UTC} [INFO] $2\e[m" ;;
    esac
}

get_current_values()
{
    # Bail out if no GNU Health profile exists
    if [ ! -e $HOME/.gnuhealthrc ]
    then
        message "ERROR" "No GNU Health profile found !"
        bailout
    fi

    # Stop if it can't find the GNU Health version
    if [ -z "$GNUHEALTH_VERSION" ]
    then
        message "ERROR" "Could not find the GNU Health version env. variable"
        bailout
    fi

    # Stop if current GNU Health version < 3.0.0
    local raw_ver=`echo $GNUHEALTH_VERSION | tr -d '.'`
    if [ $raw_ver -lt 300 ]
    then
        message "ERROR" "GNU Health version must be at least 3.0"
        bailout
    fi

    message "INFO" "Environment variables"
    message "INFO" "GNUHEALTH_VERSION = ${GNUHEALTH_VERSION}"
    message "INFO" "TRYTON VERSION = ${TRYTON_VERSION}"
    message "INFO" "PYTHONPATH = $PYTHONPATH"

}

do_backup()
{

    get_current_values

    local COMMAND=$1
    local BACKDATE=`date -u +%Y-%m-%d_%H%M%S`
    local LOCKFILE="$HOME/.gnuhealth_backup.lock"
    local INFOFILE="$HOME/gnuhealth_backup.log"
    local BACKDIR=""
    local DB=""


    shift # Remove the command and deal only with the options

    if [ $# -ne 4 ]; then
        echo -e "Usage : gnuhealth-control backup --backdir <directory> --database <dbname>"
        exit
    fi

    for option in "$@"
    do
      case $option in
          --backdir ) BACKDIR=$2;;
          --database ) DB=$2 ;;
      esac
      shift
    done

    if [ -f $LOCKFILE ]
    then
        message "ERROR" "Backup in progress or stale lock file found ..." | tee -a $INFOFILE
        bailout
    fi


    if [ ! -e ${BACKDIR} ]
    then
        message "ERROR" "Backup directory ${BACKDIR} not found !"
        bailout
    fi

    echo $$ > $LOCKFILE 

    # Backup start

    message "INFO" "START Database Backup" | tee -a $INFOFILE

    pg_dump $DB > $BACKDIR/backup\_$DB\_$BACKDATE || bailout 

    message "INFO" "Compressing Database Backup" | tee -a $INFOFILE

    gzip "${BACKDIR}/backup_${DB}_${BACKDATE}" || bailout

    message "INFO" "Compressing GNU Health home / Kernel directory" | tee -a $INFOFILE

    tar -cvzf "${BACKDIR}/gnuhealth_${DB}_fs_backup_${BACKDATE}.tar.gz" $HOME || bailout

    message "INFO" "Creating tarball with compressed DB and GNU Health home directory" | tee -a $INFOFILE

    tar -cvf "${BACKDIR}/gnuhealth_${DB}_with_fs_backup_${BACKDATE}.tar" \
        ${BACKDIR}/backup_${DB}_${BACKDATE}.gz ${BACKDIR}/gnuhealth_${DB}_fs_backup_${BACKDATE}.tar.gz \
        || bailout

    message "INFO" "Backup Successful" | tee -a $INFOFILE

    #Remove lock file
    rm $LOCKFILE

}

check_status()
{
    TRYTOND_PIDS=`pgrep -f "^.*python.*trytond.*$"`
    if [ $? = 0 ]
    then
        message "INFO" "GNU Health / Tryton instance(s) with PID(s) :"
        echo $TRYTOND_PIDS
    else
        message "INFO" "No GNU Health instance seems to be running"
    fi

}

check_download_dir()
{
    if [ -d $UPDATE_DOWNLOAD_DIR ]; then
        message "ERROR" "Update download directory exists. Bailing out"
        bailout
    fi
}

check_updates()
{
    source $HOME/.gnuhealthrc
    UTIL_DIR="${GNUHEALTH_DIR}/tryton/server/util"

    local TRYTOND_PATCHLEVEL=`echo ${TRYTON_VERSION} | cut -d'.' -f3`

    TRYTON_MAJOR_MINOR=`echo $TRYTON_VERSION | cut -d'.' -f1-2`

    GNUHEALTH_MAJOR_MINOR=`echo $GNUHEALTH_VERSION | cut -d'.' -f1-2`
    GNUHEALTH_PATCHSET=`echo $GNUHEALTH_VERSION | cut -d'.' -f3`

    GCONTROL_PATCHSET=`echo $VERSION | cut -d'.' -f3`

    NEED_UPDATE_GCONTROL=0
    NEED_UPDATE_TRYTOND=0
    NEED_UPDATE_MODULES=0
    NEED_UPDATE_PATCHSETS=0
    NEED_PATCH_TRYTON=0
    MOD_UPDATES=""
    NEED_DELETE=0
    TO_DELETE=""

    message "INFO" "GNUHEALTH-CONTROL VERSION : ${VERSION}"

    # Retrieve the latest control center that is compatible with the current GNU Health version
    LATEST_GHCONTROL=`wget --quiet -O - ${GNUHEALTH_URL} | egrep -o gnuhealth-control-${GNUHEALTH_MAJOR_MINOR}.[0-9\.]+.tar.gz | sort -V | tail -1`
    local LATEST_GHCONTROL_PATCHSET=`echo ${LATEST_GHCONTROL} | cut -d'.' -f3`
    local GHCONTROL_PATCHSET=`echo $VERSION | cut -d'.' -f3`

    if (test ${LATEST_GHCONTROL}); then
        if (( ${GHCONTROL_PATCHSET} < ${LATEST_GHCONTROL_PATCHSET} )); then
            message "WARNING" "Current version ${VERSION} is outdated. A new version (${LATEST_GHCONTROL}) is available"
            NEED_UPDATE_GCONTROL=1
        else
            message "INFO" "GNU Health control center is at the latest version ${VERSION}"
        fi
    else
        message "ERROR" "Error on getting the latest GNU Health Control Verion. Maybe a development release"
    fi

    message "INFO" "TRYTON SERVER : Checking latest patchlevel"

    LATEST_TRYTOND=`wget --quiet -O - ${TRYTON_URL}/${TRYTON_MAJOR_MINOR} | egrep -o trytond-${TRYTON_MAJOR_MINOR}.[0-9\.]+.tar.gz | sort -V | tail -1`
    local LATEST_TRYTOND_PATCHLEVEL=`echo ${LATEST_TRYTOND} | cut -d'.' -f3`

    # Check latest tryton server against local version
    if (( ${TRYTOND_PATCHLEVEL} < ${LATEST_TRYTOND_PATCHLEVEL} )); then
        message "WARNING" "TRYTON SERVER patchlevel ${TRYTOND_PATCHLEVEL} is outdated ! A newer version is available (${LATEST_TRYTOND})"
        NEED_DELETE=1
        TO_DELETE="${TO_DELETE} ${GNUHEALTH_DIR}/tryton/server/trytond-${TRYTON_MAJOR_MINOR}.${TRYTOND_PATCHLEVEL}"
        NEED_UPDATE_TRYTOND=1
    else
        message "INFO" "TRYTON SERVER patchlevel ${TRYTOND_PATCHLEVEL} is at the latest version"
    fi

    # Check latest tryton modules against local version
    cd ${GNUHEALTH_DIR}/tryton/server/modules

    for MODULE in ${TRYTON_MODULES}; do
        MOD=`ls -1d trytond_${MODULE}-*`
        message "INFO" "Checking MODULE ${MOD}"
        MODNAME=`echo $MOD | cut -d'-' -f1`
        MODULE_PATCHLEVEL=`echo $MOD | sed  's/^.*\.\([[:digit:]]*\)$/\1/'`
        LATEST_MODULE=`wget --quiet -O - ${TRYTON_URL}/${TRYTON_MAJOR_MINOR} | egrep -o ${MODNAME}-${TRYTON_MAJOR_MINOR}.[0-9\.]+.tar.gz | sort -V | tail -1`
        LATEST_MODULE_PATCHLEVEL=`echo ${LATEST_MODULE} | cut -d'.' -f3`
        if (( ${MODULE_PATCHLEVEL} < ${LATEST_MODULE_PATCHLEVEL} )); then
            message "WARNING" "${MODNAME} patchlevel ${MODULE_PATCHLEVEL} is outdated ! A newer version is available (${LATEST_MODULE})"
            NEED_UPDATE_MODULES=1
            MOD_UPDATES="${MOD_UPDATES} ${LATEST_MODULE}"
            NEED_DELETE=1
            TO_DELETE="${TO_DELETE} ${GNUHEALTH_DIR}/tryton/server/modules/${MODNAME}-${TRYTON_MAJOR_MINOR}.${MODULE_PATCHLEVEL}"
        else
            message "INFO" "${MODNAME} patchlevel ${MODULE_PATCHLEVEL} is at the latest version"
        fi
    done

    # Check latest GNU HEALTH PATCHSETS against local version
    message "INFO" "GNU HEALTH KERNEL : Checking latest PATCHSETS"

    PATCHSETS_NUM=`wget --quiet -O - ${GNUHEALTH_URL}/ | egrep -o gnuhealth_patchset-${GNUHEALTH_MAJOR_MINOR}\.[0-9\.]+.tar.gz | uniq | wc -l | tr -d ' '`

    if (( ${PATCHSETS_NUM} > 0 )); then
        message "INFO" "Number of Patchsets for this version : ${PATCHSETS_NUM}"

        LATEST_GNUHEALTH=`wget --quiet -O - ${GNUHEALTH_URL}/ | egrep -o gnuhealth_patchset-${GNUHEALTH_MAJOR_MINOR}\.[0-9\.]+.tar.gz | sort -V | tail -1`
        LATEST_GNUHEALTH_PATCHSET=`echo ${LATEST_GNUHEALTH} | cut -d'.' -f3`

        if (( ${GNUHEALTH_PATCHSET} < ${LATEST_GNUHEALTH_PATCHSET} )); then
            message "WARNING" "GNU HEALTH patchset ${GNUHEALTH_PATCHSET} is outdated ! A newer version is available (${LATEST_GNUHEALTH})"
            NEED_UPDATE_PATCHSETS=1
            let PSET=GNUHEALTH_PATCHSET+1 
            for n in `seq $PSET $LATEST_GNUHEALTH_PATCHSET`
            do
                PATCHSETS="$PATCHSETS gnuhealth_patchset-${GNUHEALTH_MAJOR_MINOR}.$n.tar.gz"
            done

        else
            message "INFO" "GNU HEALTH patchset ${GNUHEALTH_PATCHSET} is at the latest version"
        fi

    else
        message "INFO" "** NO GNU HEALTH PATCHSETS FOUND FOR THIS VERSION **"
    fi

    # CHECK SECURITY ADVISORIES AND OTHER PATCHES NOT PRESENT IN THE STANDARD TRYTON KERNEL   

    if (( ${PATCH_TRYTON} == 1 )); then
        message "INFO" "Checking Security Advisories and other patches not present in the standard tryton kernel"

            for n in ${TRYTON_PATCHES}
            do
                message "INFO" "Downloading patch for Tryton server : ${n}"
                wget --quiet --directory-prefix=${UPDATE_DOWNLOAD_DIR}/ ${GNUHEALTH_URL}/security/${n} || message "ERROR" "Could not get patch"
                message "INFO" "Checking elegibility of the patch"
                cd ${GNUHEALTH_DIR}/tryton/server/trytond-${TRYTON_VERSION}*
                patch --dry-run --silent -N -p1 < ${UPDATE_DOWNLOAD_DIR}/${n}
                if [ $? -eq 0 ]; then
                    message "WARNING" "Patch ${n} needs to be applied"
                    NEED_PATCH_TRYTON=1
                else
                    message "INFO" "Patch ${n} already applied or not elegible"
                fi

            done
    else
        message "WARNING" "PATCHING STANDARD TRYTON IS DISABLED. NO EXTRA SECURITY PATCHES OR FUNCTIONALITY WILL BE APPLIED"
    fi
}

install_updates()
{
    if [ $NEED_UPDATE_GCONTROL -eq 1 ]; then
        message "INFO" "Downloading ${LATEST_GHCONTROL} ..."
        wget --quiet --directory-prefix=${UPDATE_DOWNLOAD_DIR}/ ${GNUHEALTH_URL}/${LATEST_GHCONTROL} || bailout
        message "INFO" "Uncompressing ${LATEST_GHCONTROL} ..."        
        tar -xzf ${UPDATE_DOWNLOAD_DIR}/${LATEST_GHCONTROL} --directory ${UTIL_DIR}|| bailout
        message "INFO" "Sucessfully installed ${LATEST_GHCONTROL} "
        message "INFO" "Removing temporary download directory "
        rm -rf ${UPDATE_DOWNLOAD_DIR} || bailout
        message "INFO" "Please restart now the update with the new control center"
        exit 0

    fi

    if [ $NEED_UPDATE_TRYTOND -eq 1 ]; then
        message "INFO" "Downloading TRYTON SERVER $LATEST_TRYTOND"
        wget --quiet --directory-prefix=${UPDATE_DOWNLOAD_DIR}/trytond ${TRYTON_URL}/${TRYTON_MAJOR_MINOR}/${LATEST_TRYTOND} || bailout
        message "INFO" "--> Uncompressing TRYTON SERVER $LATEST_TRYTOND"
        tar -xzf ${UPDATE_DOWNLOAD_DIR}/trytond/${LATEST_TRYTOND} --directory ${GNUHEALTH_DIR}/tryton/server || bailout
    fi

    if [ $NEED_UPDATE_MODULES -eq 1 ]; then
        for mod in ${MOD_UPDATES}
        do
            message "INFO" "Downloading $mod"
            wget --quiet --directory-prefix=${UPDATE_DOWNLOAD_DIR}/modules ${TRYTON_URL}/${TRYTON_MAJOR_MINOR}/${mod} || bailout
            message "INFO" "--> Uncompressing ${mod}"
            tar -xzf ${UPDATE_DOWNLOAD_DIR}/modules/${mod} --directory ${GNUHEALTH_DIR}/tryton/server/modules || bailout
        done
    fi

    if [ $NEED_UPDATE_PATCHSETS -eq 1 ]; then
        for patchset in ${PATCHSETS}
        do
            message "INFO" "Downloading $patchset"
            wget --quiet --directory-prefix=${UPDATE_DOWNLOAD_DIR}/patchsets ${GNUHEALTH_URL}/${patchset} || bailout
            message "INFO" "--> Applying PATCHSET $patchset"
            tar -xzf ${UPDATE_DOWNLOAD_DIR}/patchsets/${patchset} --directory ${HOME} || bailout
        done
    fi

    # APPLY SECURITY ADVISORIES AND OTHER PATCHES NOT PRESENT IN THE STANDARD TRYTON KERNEL

    if (( ${PATCH_TRYTON} == 1 )); then
        if (( ${NEED_PATCH_TRYTON} == 1 )); then
            message "INFO" "APPLY SECURITY ADVISORIES AND OTHER PATCHES NOT PRESENT IN THE STANDARD TRYTON KERNEL"
            for n in ${TRYTON_PATCHES}
            do
                message "INFO" "Checking elegibility of the patch"
                cd ${GNUHEALTH_DIR}/tryton/server/trytond-${TRYTON_VERSION}

                patch --dry-run --silent -N -p1 < ${UPDATE_DOWNLOAD_DIR}/${n}
                if [ $? -eq 0 ]; then
                    message "WARNING" "Applying patch ${n} to Tryton kernel"
                    patch -p1 < ${UPDATE_DOWNLOAD_DIR}/${n} || bailout
                    message "INFO" "Tryton kernel sucessfully patched"
                else
                    message "INFO" "Patch ${n} already applied or not elegible"
                fi
            done
        fi
    else
        message "WARNING" "PATCHING STANDARD TRYTON IS DISABLED. NO EXTRA SECURITY PATCHES OR FUNCTIONALITY WILL BE APPLIED"
    fi

}

remove_old()
{
    if [ ${NEED_DELETE} -eq 1 ]; then
        message "WARNING" "Removing obsolete kernel and/or modules : ${TO_DELETE}"
        rm -rf ${TO_DELETE}
    fi
}

relink_mods()
{
    source $HOME/.gnuhealthrc

    if [ ${NEED_DELETE} -eq 1 ]; then
        for mod in ${TRYTON_MODULES}; do
            local modname=`ls -1d trytond_${mod}-*`
            message "INFO" "Relinking : ${mod}"
            ln -sf ${GNUHEALTH_DIR}/tryton/server/modules/${modname} ${GNUHEALTH_DIR}/tryton/server/${TRYTOND}/trytond/modules/${mod} || bailout
        done

        message "INFO" "Relinking GNU Health modules ..."
        local HEALTH_MODS=`cd ${GNUHEALTH_DIR}/tryton/server/modules; ls -1d health*`
        for mod in ${HEALTH_MODS}; do
            message "INFO" "--> Relinking : ${mod}"
            ln -sf ${GNUHEALTH_DIR}/tryton/server/modules/${mod} ${GNUHEALTH_DIR}/tryton/server/${TRYTOND}/trytond/modules/ || bailout
        done

        message "INFO" "Relinking local modules and customizations ..."

        local LOCAL_MODS=`cd ${GNUHEALTH_DIR}/tryton/server/modules/local; ls -A`
        for mod in ${LOCAL_MODS}; do
            message "INFO" "--> Relinking : ${mod}"
            ln -sf ${GNUHEALTH_DIR}/tryton/server/modules/local/${mod} ${GNUHEALTH_DIR}/tryton/server/${TRYTOND}/trytond/modules/ || bailout
        done

    fi
}

do_update()
{
    if [ $# -gt 1 ];then
        if [ $2 != "--dry-run" ];then
        message "ERROR" "Unrecognized update option"
        bailout
        fi
    fi

    check_download_dir
    get_current_values
    check_updates
    if [ $# -gt 1 ];then
        if [ $2 == "--dry-run" ];then
            cleanup
            exit 0
        fi
    fi
    install_updates
    remove_old
    relink_mods 
    cleanup
}

getlang() {
    if [ $# -eq 1 ]; then
        usage
    fi

    local lang_to_install=$2
    local lang_file=${lang_to_install}.zip
    source $HOME/.gnuhealthrc || bailout
    local lang_download_dir=$(mktemp -d /tmp/gnuhealth-XXXX)

    message "INFO" "Going to modules directory..." 

    cd ${GNUHEALTH_DIR}/tryton/server/modules || bailout
    message "INFO" "Retrieving language pack file for ${lang_to_install}" 
    wget ${TRANSLATE_URL}/download/gnu-health/-/${lang_to_install}/?format=zip -O ${lang_download_dir}/${lang_file} || bailout
    message "INFO" "Installing / Updating language files for ${lang_to_install} ..."

    ${BSDTAR} --strip-components 3 -xzf ${lang_download_dir}/${lang_file} || bailout
    message "INFO" "Language pack ${lang_to_install} sucessfully installed / updated"
    message "INFO" "You now need to update the database modules"
    message "INFO" "Removing temporary directories"
    rm -rf ${lang_download_dir}
    cd
}

install_python_dependencies() {
    message "INFO" "Updating Python dependencies..."

    # PIP names on Debian/Arch Linux based distros:
    local PIP_NAMES="pip pip3 pip-python"
    PIP_NAME=""
    for NAME in ${PIP_NAMES}; do
        if [[ $(which ${NAME} 2>/dev/null) ]]; then
            PIP_NAME=${NAME}
            break
        fi
    done

    if [[ ! ${PIP_NAME} ]]; then
        message "ERROR" "PIP command not found. Please install it or check your PATH variable."
        bailout
    fi


    local PIP_CMD=$(which $PIP_NAME)
    local PIP_VERSION="$(${PIP_CMD} --version | awk '{print $2}')"

    local PIP_ARGS="install --upgrade --user"

    # Python packages
    local PIP_LXML="lxml"
    local PIP_RELATORIO="relatorio"
    local PIP_WRAPT="wrapt"
    local PIP_WERKZEUG="werkzeug<2"
    local PIP_DATEUTIL="python-dateutil"
    local PIP_PSYCOPG2="psycopg2-binary"
    local PIP_PYTZ="pytz"
    local PIP_LDAP="python-ldap"
    local PIP_VOBJECT="vobject"
    local PIP_QRCODE="qrcode"
    local PIP_PYBARCODE="python-barcode"
    local PIP_SIX="six"
    local PIP_PILLOW="Pillow"
    local PIP_CALDAV="caldav"
    local PIP_POLIB="polib"
    local PIP_SQL="python-sql"
    local PIP_STDNUM="python-stdnum"
    local PIP_SIMPLEEVAL="simpleeval"
    local PIP_CONFIGPARSER="configparser"
    local PIP_WEBDAV3="pywebdav3-gnuhealth"
    local PIP_BCRYPT="bcrypt"
    local PIP_NUMPY="numpy"
    local PIP_UNOCONV="unoconv"
    local PIP_MAGIC="python-magic"
    local PIP_BEREN="beren==0.7.0"
    local PIP_PENDULUM="pendulum"
    local PIP_MATPLOTLIB="matplotlib"
    local PIP_PASSLIB="passlib"
    local PIP_PYCOUNTRY="pycountry==20.7.3"
    local PIP_PROGRESSBAR="progressbar==2.2"
    local PIP_DEFUSEDXML="defusedxml"


    # Operating System specific package selection
    # Skip PYTHON-LDAP installation since it tries to install / compile it system-wide

    message "WARNING" "Skipping local PYTHON-LDAP installation. Please refer to the Wikibook to install it"

    local PIP_PKGS="$PIP_NUMPY $PIP_PYTZ $PIP_WRAPT $PIP_WERKZEUG $PIP_SIX $PIP_LXML $PIP_RELATORIO $PIP_DATEUTIL $PIP_PSYCOPG2 $PIP_VOBJECT \
        $PIP_QRCODE $PIP_PYBARCODE $PIP_PILLOW $PIP_CALDAV $PIP_POLIB $PIP_SQL $PIP_STDNUM $PIP_SIMPLEEVAL $PIP_CONFIGPARSER \
        $PIP_WEBDAV3 $PIP_BCRYPT $PIP_UNOCONV $PIP_MAGIC $PIP_PASSLIB $PIP_BEREN $PIP_PENDULUM $PIP_MATPLOTLIB $PIP_PASSLIB $PIP_PYCOUNTRY \
        $PIP_PROGRESSBAR $PIP_DEFUSEDXML"

    message "INFO" "Installing python dependencies with pip-${PIP_VERSION} ..."

    for PKG in ${PIP_PKGS}; do
        message " >> ${PKG}"
        ${PIP_CMD} ${PIP_ARGS} ${PKG} || bailout
        message " >> OK"
    done
}

bailout() {
    message "ERROR" "Bailing out !"
    message "ERROR" "Removing lock files and temporary directories"
    rm -f $LOCKFILE
    rm -rf ${LANG_DOWNLOAD_DIR}
    exit 1
}

cleanup()
{
    # Delete temporary download directory
    rm -rf ${UPDATE_DOWNLOAD_DIR} || bailout
    exit 0
}

parse_command_line()
{
    if [ $# -eq 0 ]; then
        usage
    fi

    case $1 in
        version) echo $VERSION;;
        backup) do_backup $@;;
        update) do_update $@;;
        status) check_status;;
        getlang) getlang $@;;
        instpydeps)  install_python_dependencies $@;;
        help) help;;
        *) echo $1: Unrecognized command; exit 1;;
    esac
}

parse_command_line $@
