#!/bin/bash

## imunify email deploy script
# Short Description :Deploy Imunify Email 
# Description       :Installs Imunify Email Anti-Spam application
# Copyright         :Cloud Linux Zug GmbH
# License           :Cloud Linux Commercial License

readonly PACKAGE="imunifyemail"
readonly SCRIPT_VERSION="1.0.0"

readonly ETC_OS_RELEASE_FILE=${ETC_OS_RELEASE_FILE:-"/etc/os-release"}

readonly LOG_FILE=/var/log/imunifyemail-deploy.log

readonly CPANEL_INSTALL_DIR=/usr/local/cpanel
readonly CPANEL_BIN="$CPANEL_INSTALL_DIR/cpanel"

readonly SS_BIN=/usr/sbin/ss
readonly TCP_PORTS="8443"

prepend_timestamp() {
    # Prepend current time to each line
    #
    # Usage: source-program | prepend_timestamp
    #
    # Note: it may fail if the input contains \0 bytes
    while IFS= read -r line
    do
        printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"
    done
}

log() {
    # Run given command and append its duplicated stdout/stderr to
    # $LOG_FILE.
    #
    # Usage: log <command> [<args>...]
    #
    "$@" |& prepend_timestamp | tee -a "$LOG_FILE"
    return "${PIPESTATUS[0]}"
}

exit_with_error() {
    log echo "$2"
    exit "$1"
}

print_debug_info() {
    if [ "$DEBUG" == "true" ]; then
        echo "$@"
    fi
}

check_panel() {
    if [ -f $CPANEL_BIN ]; then 
      log echo "cPanel: " `$CPANEL_BIN -V`
    else 
      exit_with_error 100 "ERROR cPanel isn't detected $CPANEL_BIN"
    fi
}

check_os() {
    log echo "Checking OS version in ${ETC_OS_RELEASE_FILE}"

    if [ ! -f $ETC_OS_RELEASE_FILE ]; then
      exit_with_error 1 "ERROR Error checking os: file $ETC_OS_RELEASE_FILE doesn't exist"
    fi

    os_pretty=$(grep -oP 'PRETTY_NAME="\K[^"]+' $ETC_OS_RELEASE_FILE)
    os_id=$(grep -E "^ID=" $ETC_OS_RELEASE_FILE | cut -d = -f2)
    if ! echo "$os_id" | grep -qEi "centos|almalinux|cloudlinux" ; then
      exit_with_error 100 "ERROR OS ${os_pretty} is unsupported"
    fi

    if ! grep -oP 'VERSION_ID="\K[^"]+' $ETC_OS_RELEASE_FILE | cut -d . -f1 | grep -qE '^(7|8|9)' ; then
      exit_with_error 100 "ERROR OS ${os_pretty} has unsupported version"
    fi

    log echo "OS ${os_pretty} is supported"
}

check_exim() {
    if EXIM_BIN=`which exim 2>&1` ; then
       # log `exim --version`  # commented out for a while
       log echo $EXIM_BIN
    else
        exit_with_error 100 "ERROR No exim binary in PATH detected"
    fi
}

version_greater_equal() {
    printf '%s\n%s\n' "$2" "$1" | sort --check=quiet --version-sort
}

check_imunify() {
   if I360_BIN=`which imunify360-agent 2>&1` ; then
      I360_VERSION="$($I360_BIN version)"
      log echo "Imunify360 version: $I360_VERSION"
      if ! version_greater_equal $I360_VERSION 6.2 ; then
        log echo "WARN Imunify 360 Version must be 6.2 or greater. Please update using following command and try again:"
        log echo "WARN yum update -y imunify360-firewall"
        exit_with_error 100 "Incorrect Imunify 360 version"
      fi
      if [ -f /var/imunify360/license.json ] ; then
         chmod g+r /var/imunify360/license.json
      fi
   else
      exit_with_error 100 "ERROR No Imunify 360 Agent found"
   fi
}


install_packages () {
    log echo "Installing packages"
    _EXTRA_GROUPS=""
    if getent group mail >/dev/null ; then
        _EXTRA_GROUPS="-G mail"
    fi

    # XXX on some systems (CentOS 7, CLOS 7) nobody user id=99, together
    # with cPanel exim configuration this prevents the _imunifyemail user
    # from sending messages. Enforce uid(_imunifyemail) < uid(nobody)
    _useradd_uid_flag=$(getent passwd nobody | head -1 \
    	| awk -F: '{if ($3 == 99) { print "-u 57" } else { print "-r" }}')

    getent passwd _imunifyemail >/dev/null || \
        useradd "$_useradd_uid_flag" -g _imunify ${_EXTRA_GROUPS} \
        -d /var/imunifyemail -s /sbin/nologin \
        -c "& user" _imunifyemail
    log yum install -y $PACKAGE
}

check_ports() {
    if [ -x $SS_BIN ] ; then
        _cports=$($SS_BIN -lntH | awk -v ports="$TCP_PORTS" '
            BEGIN {
                split(ports, pa, " ");
            }
            {
                sub("^.*:", "", $4);
                oph[$4]++;
            }
            END {
                for (i in pa) {
                    if (pa[i] in oph)
                        printf("%s ", pa[i]);
                }
            }')

        if [ -n "$_cports" ] ; then
            log echo "WARN Possible conflict detected on TCP port(s): $_cports"
            return 1
        fi
    else
        log echo "ERROR Unable to verify TCP ports availability: $SS_BIN not found"
	      return 1
    fi

    return 0
}

autoconf_imunifyemail() {
    if check_ports ; then
        log ie-config -v install && log echo "The ImunifyEmail installed successfully!"
    else
        log echo "WARN The ImunifyEmail was installed, but still disabled."
        log echo "WARN Please use ie-config utility to complete manual configuration."
    fi
}

is_supported() {
  log echo "script version: ${SCRIPT_VERSION}"
  check_os
  check_panel
  check_exim
}

case "$1" in
is-supported)
  check_os
  check_panel
  check_exim
  ;;
version)
  echo "script version: ${SCRIPT_VERSION}"
  ;;
*)
  is_supported
  check_imunify
  install_packages
  autoconf_imunifyemail
	;;
esac
