#!/bin/bash

if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit 0
fi

use_colors=1
debug=1

supported_distributions=('ubuntu' 'centos')
supported_ubuntu_releases=('xenial' 'bionic' 'focal' 'jammy' 'noble')
supported_centos_releases=('7' '7 (Core)')
#supported_debian_releases='9'

#supported_distributions=('ubuntu' 'centos' 'debian')
#supported_ubuntu_releases=('xenial' 'bionic')
#supported_centos_releases=('6' '7')
#supported_debian_releases='9'

if test -n "${LOG_FILE}"; then
    echo "Redirecting output to ${LOG_FILE}"
    set -x
    exec > ${LOG_FILE} 2>&1
fi

token_dir='/opt/bunnyshell'
token_file="${token_dir}/.token"

# Check which package managers are available
apk=$(which apk 2>/dev/null || command -v apk 2>/dev/null)
apt_get=$(which apt-get 2>/dev/null || command -v apt-get 2>/dev/null)
dnf=$(which dnf 2>/dev/null || command -v dnf 2>/dev/null)
emerge=$(which emerge 2>/dev/null || command -v emerge 2>/dev/null)
equo=$(which equo 2>/dev/null || command -v equo 2>/dev/null)
pacman=$(which pacman 2>/dev/null || command -v pacman 2>/dev/null)
yum=$(which yum 2>/dev/null || command -v yum 2>/dev/null)
zypper=$(which zypper 2>/dev/null || command -v zypper 2>/dev/null)

run() {
    debug "${@}"

    output=`"${@}"`
    if test $? -ne 0; then
     error "Command failed. Output: ${output}"
    fi
}

debug() {
    if [ -n "${debug}" ]; then
        if test -z "${no_format}"; then
            if test -n "${use_colors}"; then
                echo -e "\e[0;34m[DEBUG][`date`] $@ \e[0m"
            else
                echo "[DEBUG][`date`]" "$@"
            fi
        else
            echo "$1"
        fi
    fi
}

info() {
    if test -z "${no_format}"; then
        if test -n "${use_colors}"; then
            echo -e "\e[0;32m[INFO][`date`] $1 \e[0m"
        else
            echo "[INFO][`date`] $1"
        fi
    else
        echo "$1"
    fi
}

error() {

    if test -z "${no_format}"; then
        if test -n "${use_colors}"; then
            echo -e "\e[0;31m[ERROR][`date`] $1 \e[0m"
        else
            echo "[ERROR][`date`] $1"
        fi
    else
        echo "$1"
    fi
}


detect_package_manager_from_distribution() {
    case "${1,,}" in
        arch*|manjaro*)
            package_installer="install_pacman"
            tree="arch"
            if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${pacman}" ]
                then
                error "Command 'pacman' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        sabayon*)
            package_installer="install_equo"
            tree="sabayon"
            if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${equo}" ]
                then
                error "Command 'equo' is required to install packages on a '${distribution} ${version}' system."
                # Maybe offer to fall back on emerge? Both installers exist in Sabayon...
                exit 1
            fi
            ;;

        alpine*)
            package_installer="install_apk"
            tree="alpine"
            if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${apk}" ]
                then
                error "Command 'apk' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        gentoo*)
            package_installer="install_emerge"
            tree="gentoo"
            if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${emerge}" ]
                then
                error "Command 'emerge' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        debian*|ubuntu*)
            package_installer="install_apt_get"
            tree="debian"
            if [ -z "${apt_get}" ]
                then
                error "Command 'apt-get' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        centos*|clearos*)
            info "You should have EPEL enabled to install all the prerequisites."
            info "Check: http://www.tecmint.com/how-to-enable-epel-repository-for-rhel-centos-6-5/"
            package_installer="install_yum"
            tree="centos"
            if [ -z "${yum}" ]
                then
                error "Command 'yum' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        fedora*|redhat*|red\ hat*|rhel*)
            package_installer=
            tree="rhel"
            [ ! -z "${yum}" ] && package_installer="install_yum"
            [ ! -z "${dnf}" ] && package_installer="install_dnf"
            if [ -z "${package_installer}" ]
                then
                error "Command 'yum' or 'dnf' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        suse*|opensuse*|sles*)
            package_installer="install_zypper"
            tree="suse"
            if [ -z "${zypper}" ]
                then
                error "Command 'zypper' is required to install packages on a '${distribution} ${version}' system."
                exit 1
            fi
            ;;

        *)
            error "unknown system"
                        exit 1
            ;;
    esac
}


# -----------------------------------------------------------------------------
# debian / ubuntu

validate_install_apt_get() {
    info "Checking if package '${*}' is installed..."
    [ "$(dpkg-query -W --showformat='${Status}\n' "${*}")" = "install ok installed" ] || echo "${*}"
}

install_apt_get() {

    local opts=""
    export DEBIAN_FRONTEND="noninteractive"
    opts="${opts} -yq"

        info "Running apt-get update"
        run apt-get update -y

    # install the required packages
    for pkg in "${@}"; do
            info "Adding package ${pkg}"
        run ${sudo} apt-get ${opts} install "${pkg}"
    done
}


# -----------------------------------------------------------------------------
# centos / rhel

validate_install_yum() {
    info "Checking if package '${*}' is installed..."
    yum list installed "${*}" >/dev/null 2>&1 || echo "${*}"
}

install_yum() {
    # download the latest package info
    local opts="-y"
    # install the required packages
    # install the required packages
    for pkg in "${@}"; do
            info "Adding package ${pkg}"
            run ${sudo} yum ${opts} install "${pkg}"
    done
}


# -----------------------------------------------------------------------------
# fedora

validate_install_dnf() {
    info "Checking if package '${*}' is installed..."
    dnf list installed "${*}" >/dev/null 2>&1 || echo "${*}"
}

install_dnf() {
    local opts="-y"
    opts="$opts --setopt=strict=0"
    run ${sudo} dnf ${opts} install "${@}"
}

# -----------------------------------------------------------------------------
# gentoo

validate_install_emerge() {
    echo "${*}"
}

install_emerge() {
    local opts=""

    # install the required packages
    for pkg in "${@}"; do
        [[ ${DRYRUN} -eq 0 ]] && info "Adding package ${pkg}"
        run ${sudo} emerge ${opts} -v --noreplace "${pkg}"
    done
}


# -----------------------------------------------------------------------------
# alpine

validate_install_apk() {
    echo "${*}"
}

install_apk() {
    # download the latest package info

    local opts="--force-broken-world"
    opts="${opts} -i"
    # install the required packages
    run ${sudo} apk add ${opts} "${@}"
}

# -----------------------------------------------------------------------------
# sabayon

validate_install_equo() {
    info "Checking if package '${*}' is installed..."
    equo s --installed "${*}" >/dev/null 2>&1 || echo "${*}"
}

install_equo() {
    # download the latest package info
    opts="-v"

    # install the required packages
    for pkg in "${@}"; do
        [[ ${DRYRUN} -eq 0 ]] && info "Adding package ${pkg}"
        run ${sudo} equo i ${opts} "${pkg}"
    done
}

# -----------------------------------------------------------------------------
# arch

PACMAN_DB_SYNCED=0
validate_install_pacman() {

    info "Running pacman -Sy to sync the database"
    local x=$(pacman -Sy)
    [ ! -n "${x}" ] && echo "${*}"
    PACMAN_DB_SYNCED=1

    info "Checking if package '${*}' is installed..."

    local x=""
    case "${package}" in
        "gcc")
            # Temporary workaround: In archlinux, default installation includes runtime libs under package "gcc"
            # These are not sufficient for netdata install, so we need to make sure that the appropriate libraries are there
            # by ensuring devel libs are available
            x=$(pacman -Qs "${*}" | grep "base-devel")
            ;;
        "tar")
            x=$(pacman -Qs "${*}" | grep "local/tar")
            ;;
        "make")
            x=$(pacman -Qs "${*}" | grep "local/make ")
            ;;
        *)
            x=$(pacman -Qs "${*}")
            ;;
    esac

    [ ! -n "${x}" ] && echo "${*}"
}

install_pacman() {
    # download the latest package info
    for pkg in "${@}"; do
        [[ ${DRYRUN} -eq 0 ]] && info "Adding package ${pkg}"
        # Try the noconfirm option, if that fails, go with the legacy way for non-interactive
        run ${sudo} pacman --noconfirm --needed -S "${pkg}" || yes | run ${sudo} pacman --needed -S "${pkg}"
    done
}

# -----------------------------------------------------------------------------
# suse / opensuse

validate_install_zypper() {
    rpm -q "${*}" >/dev/null 2>&1 || echo "${*}"
}

install_zypper() {
    # download the latest package info
    local opts="--ignore-unknown"
    opts="${opts} --non-interactive"

    # install the required packages
    run ${sudo} zypper ${opts} install "${@}"
}





release2lsb_release() {
        # loads the given /etc/x-release file
        # this file is normaly a single line containing something like
        #
        # X Linux release 1.2.3 (release-name)
        #
        # It attempts to parse it
        # If it succeeds, it returns 0
        # otherwise it returns 1

        local file="${1}" x DISTRIB_ID= DISTRIB_RELEASE= DISTRIB_CODENAME= DISTRIB_DESCRIPTION=
        info"Loading ${file} ..."


        x="$(cat "${file}" | grep -v "^$" | head -n 1)"

        if [[ "${x}" =~ ^.*[[:space:]]+Linux[[:space:]]+release[[:space:]]+.*[[:space:]]+(.*)[[:space:]]*$ ]]
                then
                eval "$(echo "${x}" | sed "s|^\(.*\)[[:space:]]\+Linux[[:space:]]\+release[[:space:]]\+\(.*\)[[:space:]]\+(\(.*\))[[:space:]]*$|DISTRIB_ID=\"\1\"\nDISTRIB_RELEASE=\"\2\"\nDISTRIB_CODENAME=\"\3\"|g" | grep "^DISTRIB")"
        elif [[ "${x}" =~ ^.*[[:space:]]+Linux[[:space:]]+release[[:space:]]+.*[[:space:]]+$ ]]
                then
                eval "$(echo "${x}" | sed "s|^\(.*\)[[:space:]]\+Linux[[:space:]]\+release[[:space:]]\+\(.*\)[[:space:]]*$|DISTRIB_ID=\"\1\"\nDISTRIB_RELEASE=\"\2\"|g" | grep "^DISTRIB")"
        elif [[ "${x}" =~ ^.*[[:space:]]+release[[:space:]]+.*[[:space:]]+(.*)[[:space:]]*$ ]]
                then
                eval "$(echo "${x}" | sed "s|^\(.*\)[[:space:]]\+release[[:space:]]\+\(.*\)[[:space:]]\+(\(.*\))[[:space:]]*$|DISTRIB_ID=\"\1\"\nDISTRIB_RELEASE=\"\2\"\nDISTRIB_CODENAME=\"\3\"|g" | grep "^DISTRIB")"
        elif [[ "${x}" =~ ^.*[[:space:]]+release[[:space:]]+.*[[:space:]]+$ ]]
                then
                eval "$(echo "${x}" | sed "s|^\(.*\)[[:space:]]\+release[[:space:]]\+\(.*\)[[:space:]]*$|DISTRIB_ID=\"\1\"\nDISTRIB_RELEASE=\"\2\"|g" | grep "^DISTRIB")"
        fi

        distribution="${DISTRIB_ID}"
        version="${DISTRIB_RELEASE}"
        codename="${DISTRIB_CODENAME}"

        [ -z "${distribution}" ] && error "Cannot parse this lsb-release: ${x}" && return 1
        detection="${file}"
        return 0
}

get_os_release() {
        # Loads the /etc/os-release file
        # Only the required fields are loaded
        #
        # If it manages to load /etc/os-release, it returns 0
        # otherwise it returns 1
        #
        # It searches the ID_LIKE field for a compatible distribution

        local x
        if [ -f "/etc/os-release" ]
                then
                info "Loading /etc/os-release ..."

                eval "$(cat /etc/os-release | grep -E "^(NAME|ID|ID_LIKE|VERSION|VERSION_CODENAME|VERSION_ID)=")"
                for x in "${ID}" ${ID_LIKE}
                do
                        case "${x,,}" in
                                alpine|arch|centos|debian|fedora|gentoo|sabayon|rhel|ubuntu|suse|opensuse-leap|sles)
                                        distribution="${x}"
                                        version="${VERSION_ID}"
                                        if test -n "${VERSION_CODENAME}"; then
                                            codename="${VERSION_CODENAME}"
                                        else
                                            codename="${VERSION}"
                                        fi
                                        detection="/etc/os-release"
                                        break
                                        ;;
                                *)
                                        error "Unknown distribution ID: ${x}"
                                        ;;
                        esac
                done
                [ -z "${distribution}" ] && error "Cannot find valid distribution in: ${ID} ${ID_LIKE}" && return 1
        else
                error "Cannot find /etc/os-release" && return 1
        fi

        [ -z "${distribution}" ] && return 1
        return 0
}

get_lsb_release() {
        # Loads the /etc/lsb-release file
        # If it fails, it attempts to run the command: lsb_release -a
        # and parse its output
        #
        # If it manages to find the lsb-release, it returns 0
        # otherwise it returns 1

        if [ -f "/etc/lsb-release" ]
        then
                info "Loading /etc/lsb-release ..."
                local DISTRIB_ID= ISTRIB_RELEASE= DISTRIB_CODENAME= DISTRIB_DESCRIPTION=
                eval "$(cat /etc/lsb-release | grep -E "^(DISTRIB_ID|DISTRIB_RELEASE|DISTRIB_CODENAME)=")"
                distribution="${DISTRIB_ID}"
                version="${DISTRIB_RELEASE}"
                codename="${DISTRIB_CODENAME}"
                detection="/etc/lsb-release"
        fi

        if [ -z "${distribution}" -a ! -z "${lsb_release}" ]
                then
                info "Cannot find distribution with /etc/lsb-release"
                info "Running command: lsb_release ..."
                eval "declare -A release=( $(lsb_release -a 2>/dev/null | sed -e "s|^\(.*\):[[:space:]]*\(.*\)$|[\1]=\"\2\"|g") )"
                distribution="${release[Distributor ID]}"
                version="${release[Release]}"
                codename="${release[Codename]}"
                detection="lsb_release"
        fi

        [ -z "${distribution}" ] && error "Cannot find valid distribution with lsb-release" && return 1
        return 0
}


find_etc_any_release() {
        # Check for any of the known /etc/x-release files
        # If it finds one, it loads it and returns 0
        # otherwise it returns 1

        if [ -f "/etc/arch-release" ]
                then
                release2lsb_release "/etc/arch-release" && return 0
        fi

        if [ -f "/etc/centos-release" ]
                then
                release2lsb_release "/etc/centos-release" && return 0
        fi

        if [ -f "/etc/redhat-release" ]
                then
                release2lsb_release "/etc/redhat-release" && return 0
        fi

        if [ -f "/etc/SuSe-release" ]
                then
                release2lsb_release "/etc/SuSe-release" && return 0
        fi

        return 1
}

cleanup_ip_tables_vultr() {
    which dmidecode
    exit_status=$?
    if [ $exit_status -eq 0 ]; then
        echo "dmidecode exists, will check cloud"
        cloud_dmi=`dmidecode -s system-manufacturer`
        if [ "$cloud_dmi" == "Amazon EC2" ]; then
            echo "Is Amazon cloud"
        elif [ "$cloud_dmi" == "Vultr" ]; then
            echo "Is Vultr cloud"

            which iptables
            exit_status_ip_tables=$?
            if [ $exit_status_ip_tables -eq 0 ]; then
                echo "Cleaning up ip routes table"
                iptables -P INPUT ACCEPT
                iptables -P FORWARD ACCEPT
                iptables -P OUTPUT ACCEPT
                iptables -t nat -F
                iptables -t mangle -F
                iptables -F
                iptables -X
                mkdir -p /etc/iptables
                iptables-save > /etc/iptables/rules.v4
            else
                echo "Can not clear iptables, command iptables not found"
            fi
        else
            echo "Iptables cleanup skip, not applicable for Cloud: $cloud_dmi"
        fi
    else
        echo "dmidecode does not exists"
    fi
}
echo "Cleanup ip tables in specific conditions"
cleanup_ip_tables_vultr

autodetect_distribution() {
    # autodetection of distribution
    get_os_release || get_lsb_release || find_etc_any_release

#    [ "${detection}" = "/etc/os-release" ] && cat <<EOF
#
#    /etc/os-release information:
#    NAME            : ${NAME}
#    VERSION         : ${VERSION}
#    ID              : ${ID}
#    ID_LIKE         : ${ID_LIKE}
#    VERSION_ID      : ${VERSION_ID}
#EOF

cat <<EOF

    We detected these:
    Distribution    : ${distribution}
    Version         : ${version}
    Codename        : ${codename}
    Package Manager : ${package_installer}
    Packages Tree   : ${tree}
    Detection Method: ${detection}
EOF
}

initialize_project() {

    root_dir='/opt/bunnyshell'
    mkdir -p "${root_dir}"
    exec_name='bunnyshell'

    token_dir=${root_dir}
    token_file="${token_dir}/.token"

    retry=0
    retry_timeout=5
    max_retry=20

    rm -f "${token_file}"

    while ! test -f "${token_file}"; do

        echo "Running bunnyshell --register ${project_token}"

    case ${distribution} in

        ubuntu|debian)
            TZ="`cat /etc/timezone`" SERVER_HOST="${server_host}" MODULES_PATH="${modules_path}" BUNNYSHELL_AGENT_MODULES_URL="https://static-stage-1.s3.eu-west-1.amazonaws.com/modules" ${token_dir}/${exec_name} --register ${project_token}

    ;;
    # centos)
        # TZ="`date +%Z`" SERVER_HOST="${server_host}" MODULES_PATH="${modules_path}" ${token_dir}/${exec_name} --register ${project_token}
    # ;;
        *)
            echo "Unsupported distribution ${distribution}"
            exit 1
        ;;
    esac
        if test $? -ne 0; then
            retry=$((retry + 1))

            if test $retry -eq $max_retry; then
                echo "Could not initialize agent. Max retry was reached"
                exit 1
            fi

            echo "Cannot authenticate. Trying again in ${retry_timeout} seconds"
            sleep $retry_timeout
        else
            if ! test -f "${token_file}"; then
                retry=$((retry + 1))

                if test $retry -eq $max_retry; then
                    echo "Could not initialize agent. Max retry was reached"
                    exit 1
                fi

                echo "Cannot authenticate. Trying again in ${retry_timeout} seconds"
                sleep $retry_timeout
            else
                echo "Successfully authenticated bunnyshell agent"
                break
            fi
        fi
    done
    # echo "If you want to reinitialize the srr agent project please remove ${token_file}"

}


download_tarball() {
  url="${1}"
  dest="${2}"
  name="${3}"
  opt="${4}"

  if command -v curl > /dev/null 2>&1; then
    curl -sSL --connect-timeout 10 --retry 3 "${url}" > "${dest}"
  elif command -v wget > /dev/null 2>&1; then
    wget -T 15 -O - "${url}" > "${dest}"
  else
    error "I need curl or wget to proceed, but neither is available on this system."
    exit 1
  fi

  if test $? -ne 0; then
      error "Could not download bunnyshell agent"
  fi
}

service_start() {

    info "Starting bunnyshell agent"

    if test -f '/opt/bunnyshell/.snapshot_lock'; then
      rm -rf /opt/bunnyshell/.snapshot_lock
    fi
    if test -f '/opt/bunnyshell/bunnydeploy-client'; then
echo "
#!/bin/bash

echo "Force exit if any command will return exit code != 0"

set -e

exec > /var/log/upgrade.log
exec 2>&1

echo "Begin upgrade command"
sleep 5
/bin/systemctl disable bunnydeploy.service
/usr/sbin/service bunnydeploy stop
/usr/sbin/service bunnyshell restart
echo "Finished upgrade command"
" > /opt/bunnyshell/upgrade.sh
        chmod +x /opt/bunnyshell/upgrade.sh
        cd /root
        at -f /opt/bunnyshell/upgrade.sh now
        echo "Scheduled upgrade command"
    else
        service bunnyshell restart
        if test $? -ne 0; then
            error "Could not start bunnyshell agent"
            exit 1
        fi
    fi
}

service_setup() {

    echo "SERVER_HOST=\"${server_host}\"
MODULES_PATH=\"${modules_path}\"
BUNNYSHELL_AGENT_MODULES_URL="https://static-stage-1.s3.eu-west-1.amazonaws.com/modules"
" > /opt/bunnyshell/bunnyshell.config

case ${distribution} in
    ubuntu|debian)
    TZ="`cat /etc/timezone`"
    ;;
    centos)
     TZ="`date +%Z`"
    ;;
    *)
        echo "Unsupported distribution ${distribution}"
        exit 1
    ;;
esac

echo "TZ=\"${TZ}\"" >> /opt/bunnyshell/bunnyshell.config

    if ! test -f /etc/systemd/system/bunnyshell.service; then
        cp service/bunnyshell.service /etc/systemd/system/bunnyshell.service
    systemctl daemon-reload
        systemctl enable bunnyshell.service
    fi

    if test $? -ne 0; then
        error "Cannot copy bunnyshell service file"
    fi
}

install_bunnyshell() {

    archive_name='agent'
    archive_root_path='/tmp'
    archive_path="${archive_root_path}/${archive_name}"

    # stage=""
    # prefix=""
    # if test "${server_host}" != "srr"; then
    #     stage="${server_host}/"
    #     prefix="stage."
    # fi

    #source_url="http://srr.${prefix}bunnyshell.com/${stage}modules/${archive_name}.tar.gz"
    # source_url="http://srr.${prefix}bunnyshell.com.s3.dualstack.eu-west-1.amazonaws.com/${stage}modules/${archive_name}.tar.gz"
    # source_url="https://staticfiles.ph-stage-1.bunnydemo.com/modules/${archive_name}.tar.gz"
    # source_url="https://static-stage-1.s3.eu-west-1.amazonaws.com/modules/${archive_name}.tar.gz"
    source_url="${modules_path}/modules/${archive_name}.tar.gz"
    echo "installing bunnyshnell agent from ${source_url}"

    debug "Using source ${source_url}"

    rm -rf "${archive_path}.tar.gz"
    download_tarball "${source_url}" "${archive_path}.tar.gz"
    mkdir -p ${archive_path}
    tar -xf  "${archive_path}.tar.gz" -C ${archive_path}

    if test $? -ne 0; then
        error "An error occurred while extracting archive"
        exit 1
    fi

    agent_root_path='/opt/bunnyshell'
    agent_exec="bunnyshell"
    agent_path="${agent_root_path}/${agent_exec}"

    mkdir -p "${agent_root_path}"
    cd "${archive_path}"

    if test -f "${agent_path}"; then
        mv "${agent_path}" "${agent_path}_old"
    fi

    cp ${agent_exec} ${agent_path}
 
    # temp puppet install
    wget "https://apt.puppetlabs.com/pool/bionic/puppet5/p/puppet-agent/puppet-agent_5.5.22-1bionic_amd64.deb" -P /tmp
    dpkg -i "/tmp/puppet-agent_5.5.22-1bionic_amd64.deb" > /dev/null


    # mkdir -p /etc/puppet/code/environments
    # mkdir -p /etc/puppetlabs/puppet
    # mkdir -p /etc/puppetlabs/code/environments
    # mkdir -p /etc/puppetlabs/code/modules
    # touch /etc/puppetlabs/puppet/puppet.conf

    service_setup

    initialize_project

    service_start
}



print_help() {
    echo "Bunnyshell Installer
    Usage: $0 <project_token>"
}


check_parameter() {

    if test -z "${1}"; then
        echo 1
        return 0
    fi

    echo 0
}

sanity_check() {

    feature_request_message="Please add a feature request at https://ideas.bunnyshell.com if you your like up to support Distribution ${distribution} release ${codename}"

    case ${distribution} in

    ubuntu)
        if [[ ! " ${supported_ubuntu_releases[@]} " =~ " ${codename} " ]]; then
            error "Release ${codename} is not yet supportes. Suported releases are: ${supported_ubuntu_releases[*]}. ${feature_request_message}"
            exit 1
        fi
        ;;

    centos)
        if [[ ! " ${supported_centos_releases[@]} " =~ " ${codename} " ]]; then
            error "Release ${codename} is not yet supportes. Suported releases are: ${supported_centos_releases[*]}. ${feature_request_message}"
            exit 1
        fi
        ;;
#    debian)
#        if [[ ! " ${supported_debian_releases[@]} " =~ " ${codename} " ]]; then
#            error "Release ${codename} is not yet supportes. Suported releases are ${supported_debian_releases[@]}"
#            exit 1
#        fi
#        ;;
     *)
        error "Distribution ${distribution} is not yet supported. Suported distributions are: ${supported_distributions[*]}. ${feature_request_message}"
        exit 1
        ;;
    esac

    if test -z "${project_token}"; then
        error "Please supply the project-token variable"
        print_help
        exit 1
    fi
}


install_dependencies() {
    info "Install dependencies"

    detect_package_manager_from_distribution ${distribution}
    info "Package installer: ${package_installer}"

    case ${distribution} in

    ubuntu|debian)
        PACKAGES_TO_INSTALL=(jq zip dos2unix openssl lsb-release htop at pkg-config wget unzip bc)
    ;;
    centos)
    sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
    PACKAGES_TO_INSTALL=(jq zip dos2unix openssl redhat-lsb-core htop at pkgconfig wget unzip bc bzip2)
    ;;
        *)
            echo "Unsupported distribution ${distribution}"
            exit 1
        ;;
    esac
    if [ ${#PACKAGES_TO_INSTALL[@]} -gt 0 ]; then
            info "The following command will be run: ${package_installer}" "${PACKAGES_TO_INSTALL[@]}"
            ${package_installer} "${PACKAGES_TO_INSTALL[@]}"

            if test $? -ne 0; then
                error "Cannot install all dependencies"
            fi
    fi

    # TODO ask me if I want and add automatic parameter
    which setenforce
    if test $? -eq 0; then
        echo "Disable selinux"
        setenforce 0
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
    fi

    if test "${distribution}" = 'ubuntu' -o "${distribution}" = 'debian'; then
        info "Installig aptdaemon"
        apt-get install -y aptdaemon > /dev/null
        info "Uninstalling unnatended upgrades"
        apt remove -y unattended-upgrades
    fi
}

create_user() {
    #
    # creating bunnyd group if he isn't already there
    if ! getent group bunnyd >/dev/null; then
         # Adding system group: bunnyd.
    case ${distribution} in

        ubuntu|debian)
            addgroup --system bunnyd >/dev/null
    ;;
    centos)
        groupadd --system bunnyd >/dev/null
    ;;
        *)
            echo "Unsupported distribution ${distribution}"
            exit 1
        ;;
    esac
    fi

    # creating bunnyd user if he isn't already there
    if ! getent passwd bunnyd >/dev/null; then
            # Adding system user: bunnyd.
        case ${distribution} in

            ubuntu|debian)
                  adduser \
                    --system \
                    --disabled-login \
                    --ingroup bunnyd \
                    --home /nonexistent \
                    --gecos "Bunnyshell Agent Daemon" \
                    --shell /bin/false \
                    bunnyd  >/dev/null
        ;;
        centos)
               adduser \
                    --system \
                    -r -s /bin/nologin \
                    -g bunnyd \
                    --home /nonexistent \
                    --comment "Bunnyshell Agent Daemon" \
                    --shell /bin/false \
                    bunnyd  >/dev/null
       ;;
           *)
               echo "Unsupported distribution ${distribution}"
               exit 1
           ;;
       esac
    fi
}

function create_swap() {
    total_ram=`free |awk '/^Mem:/{print $2}'`
    total_ram=$((((${total_ram} / 1000)) / 1000))

    swap=`free |awk '/^Swap:/{print $2}'`
    swap=$((((${swap} / 1000)) / 1000))

    swap_file="/swapfile_bunnyshell"
    swap_size=$((4 - ${total_ram}))

    user=`whoami`
    prefix=""
    if [ "$swap_size" -gt 0 ]; then
        if [ "$swap" -eq 0 ] && [ "$total_ram" -le "2" ]; then
            if [ "$user" != "root" ]; then
                prefix="sudo"
            fi
            if test -f "$swap_file"; then
                ${prefix} rm -f ${swap_file}
            fi
            available_space=`df -B1 / | tail -1 | awk '{print $4}'`
            available_space=$(( (( ((${available_space} / 1024)) / 1024)) / 1024))
            if [ "$available_space" -ge "$swap_size" ]; then
                if test ${distribution} == 'debian' -o ${distribution} == 'ubuntu' ; then
                    ${prefix} fallocate -l ${swap_size}G ${swap_file}
                elif test ${distribution} == 'centos'; then
                    dd if=/dev/zero of="${swap_file}" count=1024 bs=${swap_size}MiB
                fi
                ${prefix} chmod 600 ${swap_file}
                ${prefix} mkswap ${swap_file}
                ${prefix} swapon ${swap_file}
                ${prefix} cp /etc/fstab /etc/fstab.bak

                if ! grep -q "${swap_file} none swap" /etc/fstab; then
                    ${prefix} sh -c "echo \"${swap_file} none swap sw 0 0\" >> /etc/fstab"
                fi

                if ! grep -q "vm.swappiness" /etc/sysctl.conf; then
                    ${prefix} sysctl vm.swappiness=30
                    ${prefix} sh -c 'echo "vm.swappiness=30" >> /etc/sysctl.conf'
                fi
                echo 0
            fi
        fi
    else
        echo 1
    fi
}

main() {

    if test $# -lt 1; then
        print_help
        exit 1
    fi

    # installer expects params:
    # 1. token
    # 2. server_host = socket_server address (just the hostname)
    # 3. modules_path = URL for static files download (without trailing /modules segment)

    project_token=$1


    # modules_path='srr.'
    modules_path='http://srr.bunnyshell.com.s3.dualstack.eu-west-1.amazonaws.com'
    server_host='ss.srr.bunnyshell.com'

    if test -n "$2"; then
        server_host=$2
    fi

    if test -n "$3"; then
        modules_path=$3
    fi

    info "Using modules_path: ${modules_path}"
    info "Using server_host: ${server_host}"
    

    autodetect_distribution
    info "Distribution: '${distribution}'"
    info "Release codename: '${codename}'"

    sanity_check

    create_swap
    install_dependencies
    create_user

    service firewalld status 2>&1 > /dev/null

    if test $? -eq 0; then
        if [[ "$@" == *"--new"* ]]; then
            info "Disabling firewalld and replacing it with iptables"
        else
            while true; do
                echo "------------------------------------------"
                read -r -p "-- Bunnyshell needs to disable firewalld and replace it with iptables. Enter y to continue [y/n]: " answer
                case $answer in
                  [yY]) info "Disabling firewalld"; break;;
                  [nNqQ]) error "Aborting"; exit 1;;
                  *)
                esac
            done
        fi

        systemctl stop firewalld
        systemctl disable firewalld.service
    fi

    install_bunnyshell

    info "Congratulations! Bunnyshell agent is running!"
    info "Go to dashboard and in a few minutes you will see package configurations, monitoring and optimization tips!"

echo -e "\e[0;34m
   /BB\           /BB\ 
  /B.BB\         /BB.B\ 
 |BB..BB\       /BB..BB| 
 |BB...B|       |B...BB| 
 |BB...B|       |B...BB| 
  \BB..B/       \B..BB/ 
   |BB.BvBBBBBBBvB.BB| 
  /BBBBBBBBBBBBBBBBBBB\ 
 /BBBB(((BBBBBBB)))BBBB\ 
|BBBBB....BBBBB....BBBBB| 
|BBBBB....BBBBB....BBBBB| 
|BBuuuBBBB\___/BBBBuuuBB| 
|BBuuuuuBBBB|BBBBuuuuuBB| 
  \BuuuBBB\---/BBBuuuB/ 
     \BBBBBBBBBBBBB/
\e[0m"
}

main $@
exit 0

