#!/usr/bin/env sh
#set -e
#
# This script is meant for quick & easy install via:
#   'curl -sSL http://packages.onedata.org/onedatify.sh | sh -s <zone_name> <space_support_token>'
# or:
#   'wget -qO- http://packages.onedata.org/onedatify.sh | sh -s <zone_name> <space_support_token>'
#

# check to see which repo they are trying to install from
if [ -z "$repo" ]; then
    repo='main'
    url="https://packages.onedata.org"
elif [ "$repo" = "dev" ]; then
    url="http://onedata-dev-packages.cloud.plgrid.pl"
    echo "Using $url"
else
    echo "Repo \"$repo\" does not exist. Please use main or dev."
    exit 1
fi

apt_url="${url}/apt"
yum_url="${url}/yum"

package="onedatify"
onezone_url="$1"
space_support_token="$2"

if [ "$3" = "noimport" ]; then
    force_import=0
else
    force_import=1
fi
#######################################
# Utility logging and colour functions
#######################################
colors() {
  if [ -t 1 ] ; then
    def_color=$(tput sgr0 || tput me )
    red=$(tput setaf 1; tput bold || tput md)
    green=$(tput setaf 2;tput bold || tput md)
    yellow=$(tput setaf 3; tput bold || tput md)
    blue=$(tput setaf 4; tput bold || tput md)
    magneta=$(tput setaf 5; tput bold || tput md)
    cyan=$(tput setaf 6; tput bold || tput md)
    grey=$(tput setaf 7;)
    grey_bold=$(tput setaf 7 ; tput bold || tput md )
  else
    def_color=''
    red=''
    green=''
    yellow=''
    blue=''
    magneta=''
    cyan=''
    grey=''
    grey_bold=''
  fi
}
colors

log() {
  printf "$1$2$3$def_color\n"
}
_log() {
  printf "$1$2$3$def_color"
}

message() {
  log "$grey_bold" "" "$@"
}
message_imp() {
  log "$red" "" "$@"
}

_message_imp() {
  _log "$red" "" "$@"
}
_message() {
  _log "$grey_bold" "" "$@"
}

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

usage() {
cat <<EOF
This script requirers two arguments:

${0##*/} <onezone_url> <space_support_token>

Example:
${0##*/} 'https://onedata.org' 'MDAxNWxvY2F00aW9uIG9u...'

EOF
exit 1
}

if [ "$onezone_url" = "" ] ; then
    usage
fi

if [ "$space_support_token" = "" ] ; then
    usage
fi

cat <<EOF


  ______                             __              __      __   ______           
 /      \                           /  |            /  |    /  | /      \          
/\$\$\$\$\$\$  | _______    ______    ____\$\$ |  ______   _\$\$ |_   \$\$/ /\$\$\$\$\$\$  |__    __ 
\$\$ |  \$\$ |/       \  /      \  /    \$\$ | /      \ / \$\$   |  /  |\$\$ |_ \$\$//  |  /  |
\$\$ |  \$\$ |\$\$\$\$\$\$\$  |/\$\$\$\$\$\$  |/\$\$\$\$\$\$\$ | \$\$\$\$\$\$  |\$\$\$\$\$\$/   \$\$ |\$\$   |   \$\$ |  \$\$ |
\$\$ |  \$\$ |\$\$ |  \$\$ |\$\$    \$\$ |\$\$ |  \$\$ | /    \$\$ |  \$\$ | __ \$\$ |\$\$\$\$/    \$\$ |  \$\$ |
\$\$ \__\$\$ |\$\$ |  \$\$ |\$\$\$\$\$\$\$\$/ \$\$ \__\$\$ |/\$\$\$\$\$\$\$ |  \$\$ |/  |\$\$ |\$\$ |     \$\$ \__\$\$ |
\$\$    \$\$/ \$\$ |  \$\$ |\$\$       |\$\$    \$\$ |\$\$    \$\$ |  \$\$  \$\$/ \$\$ |\$\$ |     \$\$    \$\$ |
 \$\$\$\$\$\$/  \$\$/   \$\$/  \$\$\$\$\$\$\$/  \$\$\$\$\$\$\$/  \$\$\$\$\$\$\$/    \$\$\$\$/  \$\$/ \$\$/       \$\$\$\$\$\$\$ |
                                                                         /  \__\$\$ |
                                                                         \$\$    \$\$/ 
                                                                          \$\$\$\$\$\$/  
 

The onedatify script allows you to easily install Oneprovider service
and connect to existing data space

In order to install onedatify service prepare the following items:
- a fully qualified domain name (FQDN) of this machine
- valid SSL certificates issued for your FQDN
- data you would like to expose must be accessible for this machine through a POSIX path
- the command 'hostname -f' on your machine must properly return your FQDN
- operating system that supports systemd
- the following ports need to be open:

    53/TCP      DNS (Optional - used for load-balancing)
    53/UDP      DNS (Optional - used for load-balancing)
    80/TCP      HTTP
    443/TCP     HTTPS
    5555/TCP    Communication between Oneclient command line tool and Oneprovider service (TCP)
    5556/TCP    Communication between Oneprovider services among different sites
    6665/TCP    Onedata data transfer channel (RTransfer)
    6666/TCP    Onedata data transfer channel (RTransfer)
    7443/TCP    Communication between Oneprovider instances and Onezone used to exchange metadata
    8443/TCP    REST and CDMI API's (HTTP)
    8876/TCP    RTransfer protocol gateway
    8877/TCP    RTransfer protocol gateway
    9443/TCP    Onepanel web interface

EOF

proceed_with_the_installation=""
while [ "$proceed_with_the_installation" != "n" ] && [ "$proceed_with_the_installation" != "y" ] ; do
    _message "Are you ready to proceed with the installation (y|n)?: "
    read proceed_with_the_installation </dev/tty
done
if [ "$proceed_with_the_installation" = "n" ] ; then
    message "Please prepare all the requirements and rerun the script." 
    exit 1
fi

if ! command_exists systemctl ; then
	message_imp "Your system does not support systemd, the installation cannot continue."
	exit 1
fi


fqdn=$(hostname -f | grep -o '\.' | wc -l)
if [ "$fqdn" -lt 1 ] ; then
    fqdn=$(hostname -f)
    message_imp "The command 'hostame -f' reutrned $fqdn, which is not a proper FQDN. Please change the setting and rerun the script."
    exit 1
fi

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

install_docker() {
    message "Installing docker"
    #echo "$sh_c $curl"
    $sh_c "$curl https://get.docker.com/ | sh"
}

do_install() {
    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
cat >&2 <<EOF
Error: this installer needs the ability to run commands as root.
We are unable to find either "sudo" or "su" available to make this happen.
EOF
exit 1
        fi
    fi

    curl=''
    if command_exists curl; then
        curl='curl -sSL'
    elif command_exists wget; then
        curl='wget -qO-'
    fi

    message ""
    message "########################################"
    message "Onedtify installation process started..."
    message ""

    if ! command_exists docker ; then
        install_docker=""
        while [ "$install_docker" != "n" ] && [ "$install_docker" != "y" ] ; do
            _message "We detected you don't have docker installed. Would you like to install it now (y|n)?: "
            read install_docker </dev/tty
        done
        if [ "$install_docker" = "y" ] ; then
            install_docker
            if ! command_exists docker ; then
                message "Docker installation must have failed." 
                exit 1
            fi
        fi
        if [ "$install_docker" = "n" ] ; then
            message "This script cannot continue without docker."
            exit 1
        fi
    else 
        message "Docker installation found."
    fi

    if ! command_exists docker-compose ; then
        install_compose=""
        while [ "$install_compose" != "n" ] && [ "$install_compose" != "y" ] ; do
            _message "We detected you don't have docker-compose installed. Would you like to install it now (y|n)?: "
            read install_compose </dev/tty
        done
        if [ "$install_compose" = "y" ] ; then
            message "Docker-compose installation started..."
            $sh_c "$curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose"
            $sh_c "chmod +x /usr/local/bin/docker-compose"
            message "Docker-compose installed under /usr/local/bin/docker-compose"
            if ! command_exists docker-compose  ; then
                message "Docker-compose installation must have failed." 
                exit 1
            fi
        fi
        if [ "$install_compose" = "n" ] ; then
            message "This script cannot continue without docker-compose."
            exit 1
        fi
    else 
        message "Docker-compose binary was detected the machine."
    fi

    # # Temorary hack
    # if command_exists apt; then
    #     if dpkg-query -W onedatify 2>&1 2>/dev/null ; then
    #         $sh_c "apt remove -y onedatify"
    #     fi
    #     $sh_c "curl https://packages.onedata.org/apt/ubuntu/onedatify_17.06.0.rc4.systemd_amd64.deb > /tmp/onedatify-service.deb"
    #     $sh_c "dpkg -i /tmp/onedatify-service.deb"
    # else 
    #     if yum list installed onedatify 2>&1 2>/dev/null ; then
    #         $sh_c "yum remove -y onedatify"
    #     fi
    #     $sh_c "curl https://packages.onedata.org/apt/ubuntu/onedatify-service-17.06.0.rc1.systemd-1.x86_64.rpm > /tmp/onedatify-service.rpm"
    #     $sh_c "scp/tmp/onedatify-service.rpm"
    # fi
    # return 0

    # perform some very rudimentary platform detection
    lsb_dist=''
    dist_version=''
    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" ] && [ -r /etc/centos-release ]; then
        lsb_dist='centos'
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/redhat-release ]; then
        lsb_dist='redhat'
    fi
    if [ -z "$lsb_dist" ] && [ -r /etc/photon-release ]; then
        lsb_dist='photon'
    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:]')"

    # Special case redhatenterpriseserver
    if [ "${lsb_dist}" = "redhatenterpriseserver" ]; then
            # Set it to redhat, it will be changed to centos below anyways
            lsb_dist='redhat'
    fi

    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
                9)
                    dist_version="stretch"
                ;;
                8)
                    dist_version="jessie"
                ;;
                7)
                    dist_version="wheezy"
                ;;
            esac
        ;;
        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|redhat)
            dist_version="$(rpm -q --whatprovides ${lsb_dist}-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//' | sort | tail -1)"
        ;;

        "vmware photon")
            lsb_dist="photon"
            dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
        ;;

        *)
            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

    # Run setup for each distro accordingly
    case "$lsb_dist" in
        ubuntu|debian|raspbian)
            export DEBIAN_FRONTEND=noninteractive
            (
            set -x
            $sh_c "$curl ${apt_url}/onedata.gpg.key | apt-key add -"
            $sh_c "mkdir -p /etc/apt/sources.list.d"
            $sh_c "echo deb \[arch=$(dpkg --print-architecture)\] ${apt_url}/${lsb_dist}/${dist_version} ${dist_version} ${repo} > /etc/apt/sources.list.d/onedata.list"
            $sh_c "echo deb-src \[arch=$(dpkg --print-architecture)\] ${apt_url}/${lsb_dist}/${dist_version} ${dist_version} ${repo} >> /etc/apt/sources.list.d/onedata.list"
            $sh_c "sleep 3 ; apt-get update ; apt-get remove -y -q ${package}"
            $sh_c "sleep 3 ; apt-get update ; apt-get install --allow-unauthenticated -y -q ${package}"
            )
            return 0
            ;;

        fedora|centos|redhat|oraclelinux|photon)
            if [ "${lsb_dist}" = "redhat" ]; then
                # we use the centos repository for both redhat and centos releases
                lsb_dist='centos'
            fi
            if [ "${lsb_dist}" = "centos" ]; then
                # we use the centos repository for both redhat and centos releases
                dist_version=${dist_version}x
            fi
            if [ "${lsb_dist}" = "scientific" ]; then
                # we use the centos repository for both redhat and centos releases
                dist_version=${dist_version}x
            fi
            reponame="onedata-${repo}"
$sh_c "cat >/etc/yum.repos.d/onedata-${repo}.repo" <<EOF
[$reponame]
name=Onedata ${repo} Repository
baseurl=${yum_url}/${lsb_dist}/${dist_version}
enabled=1
gpgcheck=0
gpgkey=${yum_url}/gpg
EOF
            if [ "$lsb_dist" = "fedora" ] && [ "$dist_version" -ge "22" ]; then
                (
                    set -x
                    $sh_c "sleep 3; dnf -y -q install ${package}"
                )
            elif [ "$lsb_dist" = "photon" ]; then
                (
                    set -x
                    $sh_c "sleep 3; tdnf -y install ${package}"
                )
            else
                (
                    set -x
                    $sh_c "sleep 3; systemctl disable  onedatify.service"
                    $sh_c "sleep 3; yum remove -y -q ${package}"
                    $sh_c "sleep 3; yum -y -q  --disablerepo="*" --enablerepo="$reponame" install ${package}"
                )
            fi

            return 0
            ;;
    esac

    # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output
    cat >&2 <<EOF
Either your platform is not easily detectable, is not supported by this
installer script, or does not yet have a package for ${package}.
Currently supported distributions are: ubuntu wily, ubuntu xenial and fedora 23

For detailed instructions go to https://onedata.org/
EOF
    exit 1
}

run_onedatify() {
    if command_exists onedatify ; then
        message "########################################"
        message "Package installation succesfull, you will now be asked to provide configuration parameters:"
        $sh_c "onedatify '$1' '$2' '$3'"
    else
        message "'onedatify' is no avilable in your \$PATH installation must have failed."
    fi
}

# wrapped up in a function so that we have some protection against only getting
# half the file during "curl | sh"
do_install
run_onedatify "$onezone_url" "$space_support_token" "$force_import"
