#!/bin/bash

set -e

cecho() {
  local code="\033["
  case "$1" in
    black  | bk) color="${code}0;30m";;
    red    |  r) color="${code}1;31m";;
    green  |  g) color="${code}1;32m";;
    yellow |  y) color="${code}1;33m";;
    blue   |  b) color="${code}1;34m";;
    purple |  p) color="${code}1;35m";;
    cyan   |  c) color="${code}1;36m";;
    gray   | gr) color="${code}0;37m";;
    *) local text="$1"
  esac
  [ -z "$text" ] && local text="$color$2${code}0m"
  echo -e "$text"
}

command_exists() {
    command -v "$@" > /dev/null 2>&1
}

# Check if this is a forked Linux distro
check_forked() {
    # Check for lsb_release command existence, it usually exists in forked distros
    if command_exists lsb_release; then
        # Check if the `-u` option is supported
        set +e
        lsb_release -a -u > /dev/null 2>&1
        lsb_release_exit_code=$?
        set -e

        # Check if the command has exited successfully, it means we're in a forked distro
        if [ "$lsb_release_exit_code" = "0" ]; then
            # Print info about current distro
            cat <<-EOF
            You're using '$lsb_dist' version '$dist_version'.
EOF

            # Get the upstream release info
            lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[[:space:]]')
            dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[[:space:]]')

            # Print info about upstream distro
            cat <<-EOF
            Upstream release is '$lsb_dist' version '$dist_version'.
EOF
        fi
    fi
}

do_install() {

    echo ""
    cecho g "*******************************************************************************"
    cecho g "++++++                      Ishtar installation script                   ++++++"
    cecho g "*******************************************************************************"
    echo ""

    # check user
    user="$(id -un 2>/dev/null || true)"

    sh_c='sh -c'
    if [ "$user" != 'root' ]; then
        if command_exists sudo; then
            sh_c='sudo -E sh -c'
        elif command_exists su; then
            sh_c='su -c'
        else
            cecho r "  Error: this installer needs the ability to run commands as root."
            cecho r "  We are unable to find either "sudo" or "su" available to make this happen."
            exit 1
        fi
    fi

    # check distribution
    lsb_dist=''
    dist_version=''
    backports_activated=''
    igg_activated=''
    if command_exists lsb_release; then
        lsb_dist="$(lsb_release -si)"
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/lsb-release ]; then
        lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")"
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/debian_version ]; then
        lsb_dist='debian'
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/fedora-release ]; then
        lsb_dist='fedora'
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/oracle-release ]; then
        lsb_dist='oracleserver'
    fi
    if [ -z "$lsb_dist" ]; then
        if [ -r /etc/centos-release ] || [ -r /etc/redhat-release ]; then
            lsb_dist='centos'
        fi
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/os-release ]; then
        lsb_dist="$(. /etc/os-release && echo "$ID")"
    fi

    lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"

    case "$lsb_dist" in

        ubuntu)
            if command_exists lsb_release; then
                dist_version="$(lsb_release --codename | cut -f2)"
            fi
            if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
                dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
            fi
        ;;

        debian|raspbian)
            dist_version="$(cat /etc/debian_version | sed 's/\/.*//' | sed 's/\..*//')"
            case "$dist_version" in
                11)
                    dist_version="bullseye"
                ;;
                10)
                    dist_version="buster"
                ;;
                9)
                    dist_version="stretch"
                ;;
                8)
                    dist_version="jessie"
                ;;
                7)
                    dist_version="wheezy"
                ;;
            esac
            set +e
            MAINBACKS=`cat /etc/apt/sources.list | grep "contrib" | grep $dist_version'-backports' |grep -v "^#"`
            ALLBACKS=''
            if [ "$(ls -A /etc/apt/sources.list.d/)" ]; then
                ALLBACKS=`cat /etc/apt/sources.list.d/* | grep "contrib" | grep $dist_version'-backports' |grep -v "^#"`
            fi
            set -e
            if [ "$ALLBACKS" != '' ] || [ "$MAINBACKS" != '' ]; then
                backports_activated='true';
            fi

            set +e
            MAINIGG=`cat /etc/apt/sources.list | grep "deb.iggdrasil.net" | grep $dist_version |grep -v "^#"`
            ALLIGG=''
            if [ "$(ls -A /etc/apt/sources.list.d/)" ]; then
                ALLIGG=`cat /etc/apt/sources.list.d/* | grep "deb.iggdrasil.net" | grep $dist_version |grep -v "^#"`
            fi
            set -e
            if [ "$ALLIGG" != '' ] || [ "$MAINIGG" != '' ]; then
                igg_activated='true';
            fi
        ;;

        oracleserver)
            # need to switch lsb_dist to match yum repo URL
            lsb_dist="oraclelinux"
            dist_version="$(rpm -q --whatprovides redhat-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//')"
        ;;

        fedora|centos)
            dist_version="$(rpm -q --whatprovides redhat-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//')"
        ;;

        *)
            if command_exists lsb_release; then
                dist_version="$(lsb_release --codename | cut -f2)"
            fi
            if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
                dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
            fi
        ;;


    esac

    # Check if this is a forked Linux distro
    check_forked

    case "$lsb_dist" in
        ubuntu|debian|raspbian)
            ;;
        *)
            echo ""
            cecho r " Sorry. Either your platform is not easily detectable or not supported by"
            cecho r " this installer."
            echo ""
            exit 1
    esac

    default_db=''
    cat >&2 <<-'EOF'

-------------------------------------------------------------------------------
  A PostgreSQL database is needed to install Ishtar. If you do not plan to use
  a database host on another computer you need to install PostgreSQL.

EOF
    while [ "$default_db" == '' ]
    do
        cecho y '* Default PostgreSQL host? [localhost] '
        read choice
        if [ "$choice" == '' ]; then
            default_db='127.0.0.1'
        elif [ "$choice" == 'localhost' ]; then
            default_db='127.0.0.1'
        else
            default_db=$choice
        fi
    done

    webserver=''
    cat >&2 <<-'EOF'

-------------------------------------------------------------------------------
  A webserver is needed to make Ishtar available to the outside.
  Be carreful if another webserver is already configured, you'll have to serve
  your pages on a different port.

EOF
    MSG=""
    while [ "$webserver" == '' ]
    do
        cecho y '* Which webserver do you want to use? ([nginx]/none) '
        read choice
        case "$choice" in
            nginx ) webserver="nginx";;
            none ) webserver="none";;
            '' ) webserver="nginx";;
        esac
    done

    etc_path="/etc/ishtar/"
    if [ -d "$etc_path" ]; then
        echo ""
        cecho r "ERROR: it seems that "$etc_path" already exists. If this is a remnant "
        cecho r "of an old installation please delete this path before installing."
        echo ""
        exit 1
    fi

    current_locale=''
    cat >&2 <<-'EOF'

-------------------------------------------------------------------------------
  A default locale have to be set for document generation. This locale will be
  used system wide. For instance for a french installation choose: fr_FR.

EOF
    while [ "$current_locale" == '' ]
    do
        cecho y "* Which locale do you want to use? [en_US]"
        read choice
        if [ -z "$choice" ]; then
            current_locale='en_US'
        else
            current_locale=$choice
        fi
    done


    ls | grep archaeological_operations > /dev/null  || (cecho r "This script must be launch from ishtar base path with 'bash install/ishtar-install' " && exit 1)

    full_install_path=`pwd`

    install_celery=''
    cat >&2 <<-'EOF'

-------------------------------------------------------------------------------
  In order to make the consultation fluid post treatment are made intensively
  in Ishtar. If you have a lot of data (> 10 000 items) installing a dedicated
  daemon to do this post treatment is advised. This daemon is a new service
  that performs background treatments. This daemon require RabbitMQ message
  broker (auto installed).

EOF
    MSG=""
    while [ "$install_celery" == '' ]
    do
        cecho y '* Install post treatment daemon? ([no]/yes) '
        read choice
        case "$choice" in
            yes ) install_celery="yes";;
            y ) install_celery="yes";;
            no ) install_celery="no";;
            n ) install_celery="no";;
            '' ) install_celery="no";;
        esac
    done

    echo ""
    cecho g "*******************************************************************************"
    echo ""

    install_libreoffice=''
    cat >&2 <<-'EOF'

-------------------------------------------------------------------------------
  An headless version of libreoffice must be install to manage complex
  generation of documents such as ODS export with QR-codes. The installation
  of libreoffice uses ~500mo and is not advisable for installation on low-end
  devices such as raspeberry-pi.

EOF
    MSG=""
    while [ "$install_libreoffice" == '' ]
    do
        cecho y '* Install libreoffice? ([no]/yes) '
        read choice
        case "$choice" in
            yes ) install_libreoffice="yes";;
            y ) install_libreoffice="yes";;
            no ) install_libreoffice="no";;
            n ) install_libreoffice="no";;
            '' ) install_libreoffice="no";;
        esac
    done

    echo ""
    cecho g "*******************************************************************************"
    echo ""

    # Run setup for each distro accordingly
    case "$lsb_dist" in
        ubuntu|debian|raspbian)
            if [ "$dist_version" != "bullseye" ] ; then
                echo ""
                cecho r " Sorry this script cannot manage your version of Debian/Ubuntu."
                echo ""
                exit 1
            fi

            echo ""
            cecho y "Configure locale"
            echo ""

            apt-get install -y locales && \
            sed -i -e "s/# $current_locale.*/$current_locale.UTF-8 UTF-8/" /etc/locale.gen && \
            dpkg-reconfigure --frontend=noninteractive locales && \
            update-locale LANG=$LANG

            echo ""
            cecho y "Install cron script"
            echo ""

            sed -s "s|#ISHTAR_PATH#|$full_install_path|g;" \
                "install/ishtar-cron-daily" > \
                "/etc/cron.daily/ishtar"
            chmod u+x "/etc/cron.daily/ishtar"

            echo "-------------------------------------------------------------------------------";
            cecho y "Update debian packages cache";
            echo "";
            export DEBIAN_FRONTEND=noninteractive
            ( set -x; $sh_c 'sleep 3; apt-get update' )
            if ! command_exists git; then
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing git...";
                echo "";
                ( set -x; $sh_c 'sleep 3; apt-get install -y -q git' )
            fi
            if ! command_exists apg; then
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing apg...";
                echo "";
                ( set -x; $sh_c 'sleep 3; apt-get install -y -q apg' )
            fi
            if ! command_exists pip3; then
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing pip...";
                echo "";
                ( set -x; $sh_c 'sleep 3; apt-get install -y -q python3-pip' )
            fi

            echo "-------------------------------------------------------------------------------";
            cecho y "Installing dnsmasq...";
            echo "";
            ( set -x; $sh_c 'sleep 3; apt-get install -y -q dnsmasq' )

            echo "-------------------------------------------------------------------------------";
            cecho y "Installing python3-setuptools...";
            echo "";
            ( set -x; $sh_c 'sleep 3; apt-get install -y -q python3-setuptools python3-wheel' )
            if [ "$webserver" == 'nginx' ]; then
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing nginx and uwsgi...";
                echo "";
                ( set -x; $sh_c 'sleep 3; apt-get install -y -q  uwsgi uwsgi-plugin-python3 nginx' )
            fi

            if [ "$dist_version" == "bullseye" ]; then
                if [ "$default_db" == '127.0.0.1' ]; then
                    echo "-------------------------------------------------------------------------------";
                    cecho y "Installing postgresql"
                    echo ""
                    POSTGIS=postgresql-13-postgis-3
                    ( set -x; $sh_c 'sleep 3; apt-get install -y -q postgresql postgresql-contrib '$POSTGIS' '$POSTGIS'-scripts' )
                fi
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing Ishtar dependencies"
                echo "";

                if [ "$lsb_dist" == 'debian' ]; then
                    ( set -x; $sh_c 'sleep 3; apt-get install -y -q \
                       python3-bs4 \
                       python3-gdal \
                       python3-lxml \
                       python3-markdown \
                       python3-memcache \
                       python3-psycopg2 \
                       python3-pil \
                       python3-png \
                       python3-pyqrcode \
                       python3-requests \
                       python3-tidylib \
                       python3-unidecode \
                       python3-xmltodict \
                       python3-django-simple-history \
                       python3-django \
                       python3-ajax-select \
                       python3-djangorestframework \
                       python3-django-compressor \
                       python3-django-extensions \
                       python3-django-extra-views \
                       python3-django-formtools \
                       python3-django-registration \
                       apg \
                       gettext \
                       locales \
                       memcached \
                       graphviz \
                       pandoc' )
                fi

                if [ "$install_libreoffice" == 'yes' ]; then
                    ( set -x; $sh_c 'sleep 3; apt-get --no-install-recommends install -y -q \
                          libreoffice libreoffice-script-provider-python python3-uno' )
                    cp "install/libreoffice.service" "/etc/systemd/system/libreoffice.service"
                    systemctl daemon-reload
                    systemctl enable libreoffice
                    systemctl start libreoffice
                fi

                if [ "$install_celery" == 'yes' ]; then
                    ( set -x; $sh_c 'sleep 3; apt-get --no-install-recommends install -y -q \
                          rabbitmq-server' )
                    ( set -x; $sh_c 'sleep 3; apt-get install -y -q python3-celery python-celery-common' )
                    mkdir -p /var/log/celery/
                    mkdir -p /var/run/celery/
                    chown www-data:www-data /var/log/celery/ /var/run/celery/
                    mkdir -p /etc/monit/conf-available/
                fi

                echo "-------------------------------------------------------------------------------";
                cecho y "Installing django-simple-history"
                echo "";
                ( set -x; $sh_c 'pip3 install git+https://github.com/treyhunner/django-simple-history.git@1.8.2#egg=django-simple-history' )
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing python3-secretary"
                echo "";
                ( set -x; $sh_c 'pip3 install secretary==0.2.19' )
                cecho y "Installing weasyprint"
                echo "";
                ( set -x; $sh_c 'pip3 install WeasyPrint==0.42.3' )
            fi

            if [ "$install_libreoffice" == 'yes' ]; then
                ( set -x; $sh_c 'sleep 3; apt-get --no-install-recommends install -y -q \
                      libreoffice libreoffice-script-provider-python python3-uno' )
                cp "install/libreoffice.service" "/etc/systemd/system/libreoffice.service"
                systemctl daemon-reload
                systemctl enable libreoffice
                systemctl start libreoffice
            fi

            if [ "$install_celery" == 'yes' ]; then
                ( set -x; $sh_c 'sleep 3; apt-get --no-install-recommends install -y -q \
                      rabbitmq-server' )
                ( set -x; $sh_c 'sleep 3; apt-get install -y -q \
                      python3-celery python-celery-common' )

                mkdir -p /var/log/celery/
                mkdir -p /var/run/celery/
                chown www-data:www-data /var/log/celery/ /var/run/celery/
                mkdir -p /etc/monit/conf-available/
            fi

            if [ "$igg_activated" == 'true' ]; then
                ( set -x; $sh_c 'sleep 3; apt-get install -y -q \
                       python3-django-simple-history python3-secretary python3-weasyprint' )
            else
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing django-simple-history"
                echo "";
                ( set -x; $sh_c 'pip3 install git+https://github.com/treyhunner/django-simple-history.git@1.8.2#egg=django-simple-history' )
                echo "-------------------------------------------------------------------------------";
                cecho y "Installing python3-secretary"
                echo "";
                ( set -x; $sh_c 'pip3 install secretary==0.2.19' )
                cecho y "Installing weasyprint"
                echo "";
                ( set -x; $sh_c 'pip3 install WeasyPrint==0.41' )
            fi
            ;;

    esac

    mkdir -p $etc_path
    echo "ISHTAR_PATH="$full_install_path > $etc_path"config"
    echo "ISHTAR_DB="$default_db >> $etc_path"config"
    echo "ISHTAR_WEBSERVER="$webserver >> $etc_path"config"
    echo "ISHTAR_LOCALE="$current_locale >> $etc_path"config"
    echo "ISHTAR_LIB_PATH="$full_install_path >> $etc_path"config"
    echo "USE_CELERY="$install_celery >> $etc_path"config"
    echo "USE_LIBREOFFICE=yes" >> $etc_path"config"
    echo "# settings added to all instances" >> $etc_path"extra_settings.py"
    echo ""
    cecho g "*******************************************************************************"
    echo "";
    cecho g "Installation done."
    cecho g "Base configuration stored in: "$etc_path"config"
    echo ""
    echo "You can edit "$etc_path"extra_settings.py to add Django settings to all new"
    echo "instances.";
    echo "";
    cecho y "Next you will have to create an instance with: ./ishtar-prepare-instance"
    echo "";

}

do_install

