#!/bin/bash
#
# Copyright (C) 2019 OX Software GmbH
# 
# This file is part of OX Automation.
#
# OX Automation is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OX Automation is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# 
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OX Automation. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Martin Heiland <martin.heiland@open-xchange.com>
# Nikolaos Tsapanidis <nikolaos.tsapanidis@open-xchange.com>
# Benedikt Kroening <benedikt.kroening@open-xchange.com>
#
# Note, this is for TESTING ONLY, DO NOT USE IT FOR PRODUCTION

shopt -s extglob
#================================================================================
# CONFIGURATION_VARIABLES
#================================================================================
#DN=$(hostname -f)
FQDN=$(hostname -s)

if [ "$?" -ne 0 ]; then
    FQDN=$(hostname -f)
    echo "FQDN not found, using computer name: "$FQDN
fi
DN=$FQDN

DC_PRO=false
DC_REPO_SOURCE=EXT

AS_BUILDKEY="http://software.open-xchange.com/oxbuildkey.pub"
DC_BUILDKEY="https://apt.dovecot.fi/dovecot-gpg.key"

#================================================================================
# FUNCTION_DEFINITIONS
#================================================================================

function sanity_checks() {
    # Checking if we are running as root
    echo -n "Checking user... "
    if [[ $EUID -ne 0 ]]; then
        die "This script must be run as root."
    else
        ok "OK."
    fi

    # Checking OS architecture
    echo -n "Checking architecture... "
    ARCH=$(uname -m)
    if [[ "${ARCH}" != "x86_64" ]]; then
        die "Failed.\nA 64bit operating system is mandatory to install."
    else
        ok "OK."
    fi

    # FQDN check
    # ping -c 1 -q "${FQDN}" > /dev/null 2>&1
    # if [[ $? -ne 0 ]]; then
    #    die "Cannot resolve FQDN (${FQDN}), please check the network configuration."
    # fi

    # Release detection
    echo -n "Checking operating system... "
    OS=$(uname -s)
    if [[ ${OS} != "Linux" ]] ; then
        die "non-Linux.\n\nError: This installer is designed for Linux based operating systems."
    fi
    if [[ -f /etc/os-release ]]; then
        OS=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d \")
        REV=$(awk -F= '/^VERSION_ID/{print $2}' /etc/os-release | tr -d \")
        if [[ ${OS} = "debian" ]]; then
            export DEBIAN_FRONTEND=noninteractive
            if [[ ${REV} = "9" ]]; then
                DIST="DebianStretch"
                COMPATIBLE=true
                DC_REPO_PREFIX="apt"
                DC_REPO_SUFFIX="debian/stretch/ stretch main"
            elif [[ ${REV} = "8" ]]; then
                DIST="DebianJessie"
                COMPATIBLE=true
                DC_REPO_PREFIX="apt"
                DC_REPO_SUFFIX="debian/jessie/ jessie main"
            elif [[ ${REV} = "7" ]]; then
                DIST="DebianWheezy"
                COMPATIBLE=true
                DC_REPO_PREFIX="apt"
                # no wheezy packages, may fail
                DC_REPO_SUFFIX="debian/jessie/ jessie main"
            fi
        elif [[ ${OS} = "ubuntu" ]]; then
            export DEBIAN_FRONTEND=noninteractive
            if [[ ${REV} = "16.04" ]]; then
                DIST="Ubuntu_16.04"
                COMPATIBLE=true
                DC_REPO_PREFIX="apt"
                DC_REPO_SUFFIX="ubuntu/xenial xenial main"
            fi
        elif [[ ${OS} = "rhel" ]]; then
            if [[ ${REV} = "7"* ]]; then
                DIST="RHEL7"
                COMPATIBLE=true
                DC_REPO_PREFIX="yum"
                DC_REPO_SUFFIX="rhel/7/RPMS/x86_64/"
            fi
        elif [[ ${OS} = "centos" ]]; then
            if [[ ${REV} = "7"* ]]; then
                DIST="CentOS7"
                COMPATIBLE=true
                DC_REPO_PREFIX="yum"
                DC_REPO_SUFFIX="centos/7/RPMS/x86_64/"
            fi
        fi
    elif [[ -f /etc/redhat-release ]]; then
        REV=$(sed s/.*Red\ Hat\ Enterprise\ Linux\ Server\ release\ // < /etc/redhat-release | sed s/\ .*//)
        if [[ ${REV} = "6."* ]]; then
            DIST="RHEL6"
            COMPATIBLE=true
            DC_REPO_PREFIX="yum"
            DC_REPO_SUFFIX="rhel/6/RPMS/x86_64/"
        fi
        REV=$(sed s/.*CentOS\ release\ // < /etc/redhat-release | sed s/\ .*//)
        if [[ ${REV} = "6."* ]]; then
            DIST="CentOS6"
            COMPATIBLE=true
            DC_REPO_PREFIX="yum"
            DC_REPO_SUFFIX="centos/6/RPMS/x86_64/"
        fi
    fi

    if [[ -z ${COMPATIBLE} ]]; then
        echo "unknown."
        echo ""
        echo "This installer supports:"
        echo "* Debian GNU/Linux 7.0 (Wheezy)"
        echo "* Debian GNU/Linux 8.0 (Jessie)"
        echo "* Debian GNU/Linux 9.0 (Wheezy)"
        echo "* Ubuntu 16.04 (Xenial Xerus)"
        echo "* RedHat Enterprise Linux 6.0 (RHEL6)"
        echo "* RedHat Enterprise Linux 7.0 (RHEL7)"
        echo "* CentOS 6.0"
        echo "* CentOS 7.0"
        exit 1
    fi

    if [[ ${DIST} == "DebianStretch" ]] || [[ ${DIST} == "DebianJessie" ]] || [[ ${DIST} == "DebianWheezy" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
        if [[ ${DC_PRO} == true ]]; then
            #IMAP_PACKAGES="dovecot-ee-*"
            IMAP_PACKAGES="dovecot-ee-core dovecot-ee-imapd dovecot-ee-lmtpd dovecot-ee-sieve dovecot-ee-managesieved dovecot-ee-pop3d dovecot-ee-cassandra-plugin dovecot-ee-dovemon dovecot-ee-fts dovecot-ee-license dovecot-ee-lucene dovecot-ee-mail-crypt-plugin dovecot-ee-solr dovecot-ee-virtual-attachments-plugin"
        else
            IMAP_PACKAGES="dovecot-core dovecot-imapd dovecot-lmtpd dovecot-managesieved dovecot-sieve dovecot-pop3d"
        fi
        TESTER_PACKAGES="python-pip psmisc"
    else
        if [[ ${DC_PRO} == true ]]; then
            IMAP_PACKAGES="dovecot-ee-core dovecot-ee-imapd dovecot-ee-lmtpd dovecot-ee-pigeonhole dovecot-ee-managesieve dovecot-ee-pop3d dovecot-ee-cassandra-plugin dovecot-ee-dovemon dovecot-ee-fts dovecot-ee-license dovecot-ee-lucene dovecot-ee-mail-crypt-plugin dovecot-ee-solr dovecot-ee-virtual-attachments-plugin"
        else
            IMAP_PACKAGES="dovecot dovecot-pigeonhole"
        fi
    fi

}

function generate_cert() {
    echo "Generating certificate for $FQDN"
    if [[ "${DIST}" == "DebianStretch" ]] || [[ "${DIST}" == "DebianJessie" ]] || [[ "${DIST}" == "DebianWheezy" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
        SSL_DIR="/etc/ssl"
    elif [[ "${DIST}" == "RHEL6" ]] || [[ "${DIST}" == "RHEL7" ]] || [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "CentOS7" ]]; then
        SSL_DIR="/etc/pki/tls"
    fi

    openssl req -new -x509 -newkey rsa:2048 -days 3650 -nodes -subj "/CN=$FQDN" -keyout "${SSL_DIR}/private/${FQDN}.key" -out "${SSL_DIR}/certs/${FQDN}.crt"
    chmod 444 "${SSL_DIR}/certs/${FQDN}.crt"
    chmod 400 "${SSL_DIR}/private/${FQDN}.key"

}

function add_repo_info {

    echo "Adding repository information..."

    if [[ "${DC_REPO_SOURCE}" == "EXT" && ${DC_PRO} == false ]]; then
        # Using EXTernal repository 
        # Not installing PRO, using Community Edition (ce)
        # Using repo.dovecot.org build key
        DC_REPO_SRV="https://repo.dovecot.org/"
        DC_VERSION_PREFIX="ce-"
        DC_BUILDKEY="https://repo.dovecot.org/DOVECOT-REPO-GPG"

        echo "Using official dovecot community packages ... "
        URL=${DC_REPO_SRV}${DC_VERSION_PREFIX}${DC_VERSION}/${DC_REPO_SUFFIX}
    elif [[ "${DC_REPO_SOURCE}" == "EXT" && ${DC_PRO} == true ]]; then
        if [[ ${DIST} = *"Debian"* ]]; then           
            DC_REPO_SRV="https://${DC_USER}:${DC_PASS}@apt.dovecot.fi/"
        elif [[ ${DIST} == *"RHEL"* ]] || [[ ${DIST} == *"CentOS"* ]]; then          
            DC_REPO_SRV="https://${DC_USER}:${DC_PASS}@yum.dovecot.fi/"
        fi

        # Using EXTernal repository 
        # Installing PRO, using Enterprise Edition (ee, pro)
        # Using apt.dovecot.fi build key
        DC_VERSION_PREFIX="stable-"
        DC_BUILDKEY="https://apt.dovecot.fi/dovecot-gpg.key"

        echo "Using official dovecot pro packages ... "
        URL=${DC_REPO_SRV}${DC_VERSION_PREFIX}${DC_VERSION}/${DC_REPO_SUFFIX}

        # We will need 3rdparty drivers for pro:
        DC_3RD_PARTY="${DC_REPO_SRV}3rdparty/${DC_REPO_SUFFIX}"

    elif [[ "${DC_REPO_SOURCE}" == "INT" && ${DC_PRO} == true ]]; then
        if [[ ${DIST} = *"Debian"* ]]; then           
            DC_REPO_SRV="https://apt.dovecot.net/"
        elif [[ ${DIST} == *"RHEL"* ]] || [[ ${DIST} == *"CentOS"* ]]; then          
            DC_REPO_SRV="https://yum.dovecot.net/"
        fi

        # Using INTernal repository 
        # Installing PRO, using ee packages
        # Using ?? build key        
        DC_VERSION_PREFIX=""
        DC_BUILDKEY="https://repo.dovecot.org/DOVECOT-REPO-GPG" # ??

        echo "Using internal dovecot enterprise packages ... "
        URL="${DC_REPO_SRV}${DC_VERSION}/${DC_REPO_SUFFIX}"
        
        # We will need 3rdparty drivers for pro:
        DC_3RD_PARTY="${DC_REPO_SRV}3rdparty/${DC_REPO_SUFFIX}"

        # Right now there seems to be no access to the build key to the public
        # We have to override the key check
        OVERRIDE_BUILDKEY_CHECK=true
    elif [[ "${DC_REPO_SOURCE}" == "SNAPSHOT" && ${DC_PRO} == false ]]; then
        if [[ -z ${DC_USER} ]] || [[ -z ${DC_PASS} ]]; then
            die "ERROR: Missing credentials for dovecot pro repository (specify in set-install.sh)"
        fi

        if [[ ${DIST} = *"Debian"* ]]; then           
            # Using external snapshot repository 
            # SEE: https://wiki2.dovecot.org/PrebuiltBinaries
            # Not installing PRO, using Community Edition (ce)
            # Using xi.dovecot.fi build key

            DC_BUILDKEY="http://xi.dovecot.fi/debian/archive.key"
            DC_REPO_SRV="https://xi.dovecot.fi/"

            # Building debian snapshot url
            URL="${DC_REPO_SRV}debian/ "
            if [[ ${DIST} == "DebianStretch" ]]; then
                URL=${URL}"stretch"
            elif [[ ${DIST} == "DebianJessie" ]]; then
                URL=${URL}"jessie"
            elif [[ ${DIST} == "DebianWheezy" ]]; then
                URL=${URL}"wheezy"
            fi
            URL="${URL}-auto/dovecot-${DC_VERSION} main"
            
            echo "Using official dovecot snapshot packages (debian only, ce only)... "

        else
            die "ERROR: Snapshot packages are only available for Debian based distributions ..."
        fi
    fi

    
    echo "Repository url: "$URL
    if [[ -z ${URL} ]]; then
        die "ERROR: could not determine repository url ..."
    fi
    # At this time a valid repository url for the current distro is required.
    # Otherwise it may install outdated dovecot packages that are delievered with the distro

    # write repo data   
    if [[ ${DIST} == "DebianStretch" ]] || [[ ${DIST} == "DebianJessie" ]] || [[ ${DIST} == "DebianWheezy" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
        echo "deb ${URL}" > /etc/apt/sources.list.d/dovecot.list 

        if [[ -n ${DC_3RD_PARTY} ]]; then
            echo "Adding 3rd party dovecot repo ..."
            echo "deb ${DC_3RD_PARTY}" > /etc/apt/sources.list.d/dovecot-3rd.list 
        fi
    elif [[ ${DIST} == "RHEL6" ]] || [[ ${DIST} == "RHEL7" ]] || [[ ${DIST} == "CentOS6" ]] || [[ ${DIST} == "CentOS7" ]]; then

        {
            echo "[dovecot]"
            echo "name=Dovecot Repo"
            echo "baseurl=${URL}/"
            echo "enabled=1"    
        } > /etc/yum.repos.d/dovecot.repo


        {
            echo "[dovecot-3rdparty]"
            echo "name=Dovecot 3rdparty"
            echo "baseurl=${DC_3RD_PARTY}/"
            echo "enabled=1"    
        } > /etc/yum.repos.d/dovecot-3rd.repo
    fi
}

function install_packages() {
    # Adding OX App Suite and Dovecot repository build key
    echo -n "Adding OX App Suite and Dovecot repository build key..."
    if [[ "${DIST}" == "DebianStretch" ]] || [[ "${DIST}" == "DebianJessie" ]] || [[ "${DIST}" == "DebianWheezy" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
        wget -q ${AS_BUILDKEY} -O - | apt-key add -
        wget -q ${DC_BUILDKEY} -O - | apt-key add -
    elif [[ "${DIST}" == "RHEL6" ]] || [[ "${DIST}" == "RHEL7" ]]; then
        rpm --import ${AS_BUILDKEY}
        rpm --import ${DC_BUILDKEY}
    elif [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "CentOS7" ]]; then
        rpm --import ${AS_BUILDKEY}
        rpm --import ${DC_BUILDKEY}
    fi

    if [[ true == "${POSTFIX}" ]]; then
        SMTP_PACKAGES="postfix"
    fi

    PACKAGES="${IMAP_PACKAGES} ${SMTP_PACKAGES}"

    echo "Installing mail backend packages..."

    INSTALL_OPTIONS="-y "

    if [[ ${DIST} == "DebianStretch" ]] || [[ ${DIST} == "DebianWheezy" ]] || [[ ${DIST} == "DebianJessie" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
        if [[ true == "${POSTFIX}" ]]; then
            echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections
            echo "postfix postfix/mailname string $FQDN" | debconf-set-selections
            echo "postfix postfix/relayhost string \$mydomain" | debconf-set-selections
            echo "postfix postfix/protocols select all" | debconf-set-selections
            echo "postfix postfix/procmail boolean false" | debconf-set-selections
        fi

        if [[ "${OVERRIDE_BUILDKEY_CHECK}" == true ]]; then
            INSTALL_OPTIONS="${INSTALL_OPTIONS}--allow-unauthenticated "
        fi

        apt-get clean
        apt-get -qq update
        apt-get ${INSTALL_OPTIONS} install ${PACKAGES} ${TESTER_PACKAGES}
    elif [[ ${DIST} == "RHEL6" ]] || [[ ${DIST} == "RHEL7" ]]; then
        if [[ "${OVERRIDE_BUILDKEY_CHECK}" == true ]]; then
            INSTALL_OPTIONS="${INSTALL_OPTIONS}--nogpgcheck "
        fi

        subscription-manager refresh
        yum clean all
        yum ${INSTALL_OPTIONS} install ${PACKAGES} ${TESTER_PACKAGES}
    elif [[ ${DIST} == "CentOS6" ]] || [[ ${DIST} == "CentOS7" ]]; then
        if [[ "${OVERRIDE_BUILDKEY_CHECK}" == true ]]; then
            INSTALL_OPTIONS="${INSTALL_OPTIONS}--nogpgcheck "
        fi
        yum clean all
        yum ${INSTALL_OPTIONS} install ${PACKAGES} ${TESTER_PACKAGES}
    fi
}

function configure_postfix() {
    echo "Configure postfix main.cf"
    postconf -e "myorigin = \$mydomain"
    postconf -e "mydestination = "
    postconf -e "relayhost = "\$mydomain
    postconf -e "smtpd_tls_cert_file=${SSL_DIR}/certs/${FQDN}.crt"
    postconf -e "smtpd_tls_key_file=${SSL_DIR}/private/${FQDN}.key"
    postconf -e "dovecot_destination_recipient_limit = 1"
    postconf -e "virtual_mailbox_domains = $FQDN, $DN, $DN.localdomain"
    postconf -e "virtual_transport = dovecot"

    echo "Configure postfix master.cf"
    # uncomment the next line if you want debug output
    #postconf -M smtp/inet="smtp	  inet  n	   -	   -	   -	   -	   smtpd -v"

    if [[ ${DIST} == "DebianStretch" ]] || [[ ${DIST} == "DebianWheezy" ]] || [[ ${DIST} == "DebianJessie" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
        LDA_PATH="/usr/lib/dovecot/dovecot-lda"
    else
        LDA_PATH="/usr/libexec/dovecot/dovecot-lda"
    fi


    echo "dovecot     unix     -     n     n     -     -     pipe" >> /etc/postfix/master.cf
    echo "  flags=DRhu user=vmail:vmail argv=${LDA_PATH} -f \${sender} -d \${user}" >> /etc/postfix/master.cf
}

function configure_dovecot() {
    echo "Configure dovecot"
    DC_CONF_DIR="/etc/dovecot/conf.d/"

    if [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "CentOS7" ]]; then
        selinuxenabled
        if [ $? -ne 0 ]
        then
            echo "Selinux not enabled"
        else
            echo "Enabling selinux dovecot policies"
            semanage permissive -a dovecot_t
        fi
    fi

    if [[ true == "${DC_PRO}" ]]; then
        if [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "CentOS7" ]] || [[ "${DIST}" == "RHEL6" ]] || [[ "${DIST}" == "RHEL7" ]]; then
            DC_DEFAULT_CONF_DIR="/usr/share/doc/dovecot-ee-*/example-config/conf.d/"
            declare -a CONF_FILE_LIST=("10-mail.conf" "10-master.conf" "10-auth.conf" "10-ssl.conf" "10-logging.conf" "15-lda.conf" "20-imap.conf" "20-managesieve.conf" "90-quota.conf" "90-plugin.conf" "90-sieve.conf" "90-acl.conf" "auth-static.conf.ext" "../dovecot.conf")
        elif [[ "${DIST}" == "DebianStretch" ]] || [[ "${DIST}" == "DebianWheezy" ]] || [[ "${DIST}" == "DebianJessie" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
            DC_DEFAULT_CONF_DIR="/usr/share/doc/dovecot-ee-core/example-config/conf.d/"
            declare -a CONF_FILE_LIST=("10-master.conf" "10-logging.conf" "15-lda.conf" "10-ssl.conf" "20-imap.conf" "20-managesieve.conf" "90-quota.conf" "90-plugin.conf" "90-acl.conf" "auth-static.conf.ext")

            cp /usr/share/doc/dovecot-ee-core/example-config/conf.d/10-mail.conf "${DC_CONF_DIR}"10-mail.conf
            cp /usr/share/doc/dovecot-ee-core/example-config/conf.d/10-auth.conf "${DC_CONF_DIR}"10-auth.conf
            cp /usr/share/doc/dovecot-ee-core/example-config/dovecot.conf "${DC_CONF_DIR}"../dovecot.conf
            gunzip /usr/share/doc/dovecot/example-config/conf.d/90-sieve.conf.gz -c > "${DC_CONF_DIR}"90-sieve.conf
            cp /usr/share/doc/dovecot/example-config/conf.d/20-managesieve.conf "${DC_CONF_DIR}"20-managesieve.conf
        fi
    else
        DC_DEFAULT_CONF_DIR="/usr/share/dovecot/conf.d/"
        declare -a CONF_FILE_LIST=("20-imap.conf" "20-managesieve.conf" "90-sieve.conf" "../dovecot.conf")
    fi

    for file in "${CONF_FILE_LIST[@]}"
    do
        if [ ! -f "${DC_CONF_DIR}/${file}" ]
            then
            echo -n "Copying $file to ${DC_CONF_DIR}... "
            cp ${DC_DEFAULT_CONF_DIR}${file} ${DC_CONF_DIR}${file}
            ok "OK"
        fi
    done

    echo "Backing up config files"
    for file in "10-mail.conf" "10-master.conf" "10-auth.conf" "10-ssl.conf" "auth-static.conf.ext" "10-logging.conf" "15-lda.conf" "20-imap.conf" "20-managesieve.conf" "90-quota.conf" "90-acl.conf" "90-plugin.conf"
    do
        echo -n "Renaming file ${file} to ${file}.orig... "
        mv -- "${DC_CONF_DIR}${file}" "${DC_CONF_DIR}${file}.orig"
        echo "OK"
    done

    # dovecot.conf
    sed -i '/\!include\_try.*protocol/a protocols = imap lmtp' /etc/dovecot/dovecot.conf

    # 10-mail.conf
    if [[ "${DC_VERSION}" == "2.3" ]] || [[ "${DC_VERSION}" > "2.3."* ]]; then
        DC_MAIL_PLUGINS="acl mail_log notify quota old_stats virtual zlib"
    else
        DC_MAIL_PLUGINS="acl mail_log notify quota stats virtual zlib"
    fi

    if [[ "${DC_VERSION}" > "2.2.27"* ]] || [[ "${DC_REPO}" == "nightly" ]]; then
      cat > "${DC_CONF_DIR}"/10-mail.conf <<EOF
mail_vsize_bg_after_count = 100
EOF
    fi

    cat >> "${DC_CONF_DIR}"/10-mail.conf <<EOF
mailbox_list_index = yes
mail_always_cache_fields = body.snippet
mail_location = maildir:~/Maildir
mail_uid = vmail
mail_gid = vmail
EOF

    if [[ true == "${DC_PRO}" ]]; then
        cat >> "${DC_CONF_DIR}"/10-mail.conf <<EOF
mail_plugins = \$mail_plugins ${DC_MAIL_PLUGINS} virtual_attachments
EOF
    else
        cat >> "${DC_CONF_DIR}"/10-mail.conf <<EOF
mail_plugins = \$mail_plugins ${DC_MAIL_PLUGINS}
EOF
    fi

    cat >> "${DC_CONF_DIR}"/10-mail.conf <<EOF

namespace inbox {
  inbox = yes
  prefix = INBOX/
  separator = /
}

namespace {
  type = shared
  separator = /
  prefix = shared/%%u/
  location = maildir:%%h/Maildir:INDEX=%h/shared/%%u:CONTROL=%h/shared/%%u
  subscriptions = yes
  list = children
}
EOF

    if [[ "${DIST}" != "CentOS6" ]] && [[ "${DIST}" != "RHEL6" ]]; then
    cat >> "${DC_CONF_DIR}"/10-mail.conf <<EOF
namespace virtual {
  prefix = virtual/
  separator = /
  hidden = yes
  list = no
  subscriptions = no
  location = virtual:/var/lib/dovecot/virtual:INDEX=~/Maildir/virtual
  mailbox all {
    special_use = \All
  }
}
EOF
    fi

    if [[ ${DC_PRO} == true ]]; then
    cat >> "${DC_CONF_DIR}"/10-mail.conf <<EOF
namespace virtualattachments {
  prefix = VirtualAttachments/
  separator = /
  hidden = yes
  list = no
  subscriptions = no
  location = attachments:~/Maildir/virtual-attachments
  mailbox INBOX {
    auto = create
  }
  mailbox "INBOX/Sent Items" {
    auto = create
  }
  mailbox virtual/all {
    auto = create
    special_use = \All
  }
}
EOF
    fi

    # TLS cert
    if [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "CentOS7" ]] || [[ "${DIST}" == "RHEL6" ]] || [[ "${DIST}" == "RHEL7" ]]; then
    DC_CERT_FILE="/etc/pki/dovecot/certs/dovecot.pem"
    DC_KEY_FILE="/etc/pki/dovecot/private/dovecot.pem"
    elif [[ "${DIST}" == "DebianStretch" ]] || [[ "${DIST}" == "DebianWheezy" ]] || [[ "${DIST}" == "DebianJessie" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
      if [[ true == "${DC_PRO}" ]]; then
        DC_CERT_FILE="/etc/ssl/certs/dovecot.pem"
        DC_KEY_FILE="/etc/ssl/private/dovecot.pem"
      else
        DC_CERT_FILE="/etc/dovecot/dovecot.pem"
        DC_KEY_FILE="/etc/dovecot/private/dovecot.pem"
      fi
    fi

    if [[ "${DIST}" == "CentOS7" ]] || [[ "${DIST}" == "RHEL7" ]]; then
      if [[ true == "${DC_PRO}" ]]; then
        cd /usr/share/doc/dovecot-ee-+([0-9])*
      else
        cd /usr/share/doc/dovecot-+([0-9])*
      fi
    elif [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "RHEL6" ]]; then
      if [[ true == "${DC_PRO}" ]]; then
        cd /usr/share/doc/dovecot-ee-+([0-9])*
      else
        cd /usr/libexec/dovecot/
      fi
    elif [[ "${DIST}" == "DebianStretch" ]] || [[ "${DIST}" == "DebianWheezy" ]] || [[ "${DIST}" == "DebianJessie" ]] || [[ ${DIST} == "Ubuntu_16.04" ]]; then
      if [[ true == "${DC_PRO}" ]]; then
        cd /usr/share/doc/dovecot-ee-core/
      else
        cd /usr/share/dovecot/
      fi
    fi

    # 10-ssl.conf
    cat > "${DC_CONF_DIR}"/10-ssl.conf <<EOF
ssl = yes
ssl_cert = <${DC_CERT_FILE}
ssl_key = <${DC_KEY_FILE}
EOF

    if [[ "${DC_VERSION}" == "2.3" ]] || [[ "${DC_VERSION}" > "2.3."* ]]; then
      DC_SSL_DH_FILE="/etc/dovecot/dh.pem"
      echo "Generating ssl dh file with openssl dhparam 1024 at ${DC_SSL_DH_FILE}"
      openssl dhparam -out ${DC_SSL_DH_FILE} 1024
      cat >> "${DC_CONF_DIR}"/10-ssl.conf <<EOF
ssl_dh = <${DC_SSL_DH_FILE}
EOF
    fi
    bash mkcert.sh

    # 10-master.conf
    cat > "${DC_CONF_DIR}"/10-master.conf <<EOF
service auth {
  unix_listener auth-userdb {
    mode = 0666
    user = vmail
    group = vmail
  }
}
EOF

    # 10-auth.conf
    cat > "${DC_CONF_DIR}"/10-auth.conf <<EOF
disable_plaintext_auth = no
auth_mechanisms = plain
!include auth-static.conf.ext
EOF

    # auth-static.conf.ext
    cat > "${DC_CONF_DIR}"/auth-static.conf.ext <<EOF
passdb {
  driver = static
  args = password=secret
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/home/vmail/%u
}
EOF

    # 10-logging.conf
    cat > "${DC_CONF_DIR}"/10-logging.conf <<EOF
#log_path = /var/log/dovecot.log
auth_verbose = yes
plugin {
  mail_log_events = delete undelete expunge copy flag_change append mailbox_delete mailbox_rename
  mail_log_fields = uid box msgid size
}
EOF

    # 15-lda.conf
    cat > "${DC_CONF_DIR}"/15-lda.conf <<EOF
protocol lda {
  mail_plugins = \$mail_plugins sieve
}
postmaster_address = invalid@invalid.invalid
EOF

    if [[ "${DC_VERSION}" == "2.3" ]] || [[ "${DC_VERSION}" > "2.3."* ]]; then
        DC_IMAP_PLUGINS="imap_acl imap_quota imap_old_stats imap_filter_sieve"
    else
        DC_IMAP_PLUGINS="imap_acl imap_quota imap_stats"
    fi

    # 20-imap.conf
    cat > "${DC_CONF_DIR}"/20-imap.conf <<EOF
imap_capability = +SEARCH=X-MIMEPART XDOVECOT
protocol imap {
  mail_plugins = \$mail_plugins ${DC_IMAP_PLUGINS}
}
EOF

    # 20-managesieve.conf
    cat > "${DC_CONF_DIR}"/20-managesieve.conf <<EOF
protocols = \$protocols sieve
service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
}
EOF

    # 90-quota.conf
    cat > "${DC_CONF_DIR}"/90-quota.conf <<EOF
plugin {
  quota = count:User quota
  quota_rule = *:storage=1G
  quota_rule2 = INBOX/Trash:storage=+100M
  quota_grace = 10%%
}
plugin {
  quota = maildir:User quota
}
EOF

    # 90-acl.conf
    cat > "${DC_CONF_DIR}"/90-acl.conf <<EOF
plugin {
  acl = vfile
  acl_shared_dict = file:/var/lib/dovecot/db/shared-mailboxes.db
}
EOF

    # 91-stats.conf
    if [[ "${DC_VERSION}" == "2.3" ]] || [[ "${DC_VERSION}" > "2.3."* ]]; then
      cat >> "${DC_CONF_DIR}"/91-stats.conf <<EOF
service old-stats {
  fifo_listener old-stats-mail {
    user = vmail
    mode = 0600
  }
  ## permission denied issues @RHEL
  #inet_listener {
  #  address = 127.0.0.1
  #  port = 24242
  #}
}
EOF
    else
      cat >> "${DC_CONF_DIR}"/91-stats.conf <<EOF
service stats {
  fifo_listener stats-mail {
    user = vmail
    mode = 0600
  }
  ## permission denied issues @RHEL
  #inet_listener {
  #  address = 127.0.0.1
  #  port = 24242
  #}
}
EOF
    fi

}

function prerequisites() {
    echo "Creating user and group: vmail"
    groupadd -g 5000 vmail
    useradd -u 5000 -g 5000 -m -d /home/vmail -s /bin/false vmail
    chown -R vmail:vmail /home/vmail
    chmod 2770 /home/vmail

    echo "Creating directory for dovecot acl informations"
    mkdir -p /var/lib/dovecot/db
    chmod 0770 /var/lib/dovecot

    echo "Creating dictionary for shared namespace"
    touch /var/lib/dovecot/db/shared-mailboxes.db

    echo "Creating virtual directories"
    mkdir -p /var/lib/dovecot/virtual/all
    chmod -R 700 /var/lib/dovecot/virtual

    echo "*
-INBOX/Trash
-INBOX/Trash/*
-INBOX/Spam
-INBOX/Spam/*
  all" > /var/lib/dovecot/virtual/all/dovecot-virtual

  chown -R vmail:vmail /var/lib/dovecot
}

function restart_services() {
    if [[ "${DIST}" == "DebianWheezy" ]] || [[ "${DIST}" == "CentOS6" ]] || [[ "${DIST}" == "RHEL6" ]]; then
        service dovecot restart
        if [[ true == "${POSTFIX}" ]]; then
            service postfix restart
        fi
    else
        systemctl unmask dovecot.service
        systemctl enable dovecot.service
        systemctl restart dovecot.service
        if [[ true == "${POSTFIX}" ]]; then
            systemctl restart postfix.service
        fi
    fi
}

# Green
function ok() {
    echo -e '\e[32m'${1}'\e[m';
}

# Red
function die() {
    echo -e '\e[1;31m'${1}'\e[m';
    exit 1;
}

function usage() {
echo -n "
  $0 [OPTIONS]

When not providing any option, the script will attempt to source \"set-install.sh\". If no information can be found, the distribution specific Dovecot package is being installed as fallback.

OPTIONS:
  -e	Sets the environment, e.g. \"release\" or \"nightly\"
  -v	Sets the version, e.g. \"2.2.26.1-10\" or \"2.2\"
  -p	Use Dovecot Pro
  -s	Installs and configures a SMTP service (Postfix)
  -h	Display this help and exit
"
}

#================================================================================
# MAIN_CODE
#================================================================================

while getopts "he::v::ps" OPTION
do
    case ${OPTION} in
        h)
            usage
            exit 1
            ;;
        e)
            DC_REPO=${OPTARG}
            ;;
        v)
            DC_VERSION=${OPTARG}
            ;;
        p)
            DC_PRO=true
            ;;
        s)
            POSTFIX=true
            ;;
        \?)
            echo "Invalid option: -${OPTARG}" >&2
            usage
            exit 1
            ;;
        :)
            echo "Option -${OPTARG} requires an argument." >&2
            exit 1
            ;;
    esac
done


if [[ -z "${DC_VERSION}" ]]; then
    echo "Version not specified, sourcing set-install.sh."
    source set-install.sh

    if [[ -z "${DC_VERSION}" ]]; then
        echo "DC_VERSION environment variable still not set"
        die "No dovecot version specified. Either set DC_VERSION in set-install.sh or as environment variable. Or use the parameter '-v'"
    fi
fi

# if [[ -z "${DC_REPO}" ]] && [[ -z "${DC_VERSION}" ]]; then
#     echo "Repository and version not specified, sourcing set-install.sh."
#     source set-install.sh
#     if [[ -n "${DC_REPO}" ]] && [[ "EXT" == "${DC_REPO_SOURCE}" ]]; then
#         if [[ -n "${DC_USER}" ]] && [[ -n "${DC_PASS}" ]]; then
#             echo "Found credentials for Dovecot Pro repository."
#             DC_REPO="${DC_REPO}"
#             DC_PRO=true

#             # todo: re-implement ...
#             die "Enterprise dovecot with custom credentials not yet re-implemented"
#         # else
#         #     echo "No Dovecot Pro repository credentials found, fallback to distro specific Dovecot"
#         #     DC_PRO=false
#         fi
#     # elif [[ -n "${DC_REPO}" ]] && [[ "OBS" == "${DC_REPO_SOURCE}" ]]; then
#     #     echo "Using internal repository source"
#     # else
#         # echo "No repo settings found at set-install.sh, fallback to distro specific Dovecot."
#         # DC_PRO=false
#     fi
# fi

sanity_checks
prerequisites
generate_cert
add_repo_info
INSTALLCOUNT=0
while [[ ${INSTALLCOUNT} -lt 6 ]]; do
        install_packages
        if [[ $? -ne 0 ]]; then
            INSTALLCOUNT=$((INSTALLCOUNT+1))
            echo "Error while installing packages, retrying in 30s ($INSTALLCOUNT/5)."
            sleep 30
        else
            break
        fi
done
if [[ ${INSTALLCOUNT} -ge 5 ]]; then
    echo "Error while installing packages, aborting."
    exit 1
fi
if [[ true == "${POSTFIX}" ]]; then
    configure_postfix
fi
configure_dovecot
restart_services

echo "
Installation complete, thanks for using Dovecot. Have a lot of fun!
"
