#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

#set -x

PILER_HOSTNAME="${PILER_HOSTNAME:-archive.yourdomain.com}"
MYSQL_ROOT_PASSWORD="abcde123"
MYSQL_PILER_PASSWORD="piler123"
ENCRYPT_MYSQL_DATA_AT_REST=0
AUTH_CODE="${AUTH_CODE:-fNNJADYT0EILtrD7hxh}"
NODE_TYPE="${NODE_TYPE:-WORKER}"
PRIMARY_MASTER="${PRIMARY_MASTER:-0}"
MULTITENANCY="${MULTITENANCY:-0}"
MULTINODES="${MULTINODES:-0}"
MASTER_NODE="${MASTER_NODE:-10.1.1.2}"
SERVER_ID="${SERVER_ID:-0}"
USE_SMTP_GATEWAY="${USE_SMTP_GATEWAY:-0}"
SPHINX_WORKER_LISTEN_ADDRESS="${SPHINX_WORKER_LISTEN_ADDRESS:-}"
PHP_FPM_SOCKET="/var/run/php/php7.4-fpm.sock"
DISTRO="focal"
PILER_VERSION="1.7.0"

MYSQL_HOSTNAME="localhost"
MYSQL_DATABASE="piler"
MYSQL_USERNAME="piler"

APACHE_TIKA="tika-server-1.25.jar"
TRAEFIK="traefik-2.4.8"
DOWNLOAD_URL="https://download.mailpiler.com"
COMMIT_ID="$(curl -k -s ${DOWNLOAD_URL}/piler-ee/piler-ee.tag)"
PILER_DEB="piler-ee_${PILER_VERSION}-${DISTRO}-${COMMIT_ID}_amd64.deb"
PILER_USER="piler"
CONFIG_SITE_PHP="/etc/piler/config-site.php"

export DEBIAN_FRONTEND=noninteractive

install_prerequisites() {
   wget https://repo.manticoresearch.com/manticore-repo.noarch.deb
   dpkg -i manticore-repo.noarch.deb
   apt-get update
   apt-get install -y manticore manticore-columnar-lib
   apt-get -y --no-install-recommends install wget rsyslog openssl sysstat unzip php7.4-cli php7.4-cgi php7.4-mysql php7.4-fpm php7.4-zip php7.4-ldap php7.4-gd php7.4-curl php7.4-xml php7.4-mbstring php-memcached nginx sudo libtre5 libzip5 zip libmariadb-dev mariadb-server cron openjdk-8-jre memcached python3-pip python3-mysqldb netcat
   pip install imapclient minio==7.1.5
   wget -O /usr/local/bin/traefik "${DOWNLOAD_URL}/generic-local/${TRAEFIK}"
   chmod +x /usr/local/bin/traefik
   setcap cap_net_bind_service+ep /usr/local/bin/traefik
   systemctl stop manticore
}


setup_mysql_encryption() {
   local s

   ### See https://mariadb.com/kb/en/file-key-management-encryption-plugin/ for more

   mkdir -p /etc/mysql/encrypt
   chown mysql:mysql /etc/mysql/encrypt
   chmod 700 /etc/mysql/encrypt
   s="$(openssl rand -hex 32)"
   echo "1;${s}" > /etc/mysql/encrypt/keyfile
   openssl rand -hex 128 > /etc/mysql/encrypt/keyfile.key
   openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/encrypt/keyfile.key -in /etc/mysql/encrypt/keyfile -out /etc/mysql/encrypt/keyfile.enc
   rm -f /etc/mysql/encrypt/keyfile

   cat > /etc/mysql/mariadb.conf.d/99-encrypt.cnf << ENCRYPT_CNF
[mariadb]

plugin_load_add = file_key_management
loose_file_key_management_filename = /etc/mysql/encrypt/keyfile.enc
loose_file_key_management_filekey = FILE:/etc/mysql/encrypt/keyfile.key
loose_file_key_management_encryption_algorithm = AES_CBC
ENCRYPT_CNF

}


fix_mysql_settings() {
   cat > /etc/mysql/mariadb.conf.d/99-piler.cnf << PILER_CNF
[mysqld]

innodb_buffer_pool_size=512M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=64M
innodb_log_file_size=64M
innodb_read_io_threads=4
innodb_write_io_threads=4
innodb_log_files_in_group=2

innodb_file_per_table
PILER_CNF
}

start_mysql() {
   fix_mysql_settings
   [[ $ENCRYPT_MYSQL_DATA_AT_REST -eq 1 ]] && setup_mysql_encryption

   service mysql restart
   mysqladmin -u root password "${MYSQL_ROOT_PASSWORD}"
}


install_piler() {
   wget -q --no-check-cert "${DOWNLOAD_URL}/piler-ee/${PILER_DEB}"
   dpkg -i "$PILER_DEB"

   if test "$NODE_TYPE" = "MASTER"; then
      sed -i 's/#CREATE_CUSTOMER/1,16,31,46/' /usr/share/piler/piler.cron
      sed -i 's/#ON_GUI//g' /usr/share/piler/piler.cron
   else
      sed -i 's/#CREATE_CUSTOMER/20/' /usr/share/piler/piler.cron
      sed -i 's/#ON_WORKER//g' /usr/share/piler/piler.cron
   fi

   crontab -u "$PILER_USER" /usr/share/piler/piler.cron

   rm -f "$PILER_DEB" /etc/nginx/sites-enabled/default
   ln -sf /etc/piler/piler-nginx.conf /etc/nginx/sites-enabled/piler.conf
   wget -q -O "/var/piler/tika/tika-server.jar" "${DOWNLOAD_URL}/generic-local/${APACHE_TIKA}"

   touch /var/piler/.bash_history
   chown "${PILER_USER}:${PILER_USER}" /var/piler/.bash_history

   if [[ $ENCRYPT_MYSQL_DATA_AT_REST -eq 1 ]]; then
      touch /etc/piler/ENCRYPTED_DATABASE
   fi

   touch /etc/piler/MANTICORE
}


create_my_cnf() {
   local user=$1
   local password=$2
   local my_cnf=$3

   printf "[client]\\n\\nhost = %s\\nuser = %s\\npassword = %s\\n" "$MYSQL_HOSTNAME" "$user" "$password" > "$my_cnf"
   printf "\\n\\n[mysqldump]\\n\\nhost = %s\\nuser = %s\\npassword = %s\\n" "$MYSQL_HOSTNAME" "$user" "$password" >> "$my_cnf"
   chown $PILER_USER:$PILER_USER "$my_cnf"
   chmod 600 "$my_cnf"
}


fix_config_site_php() {
   sed -i -e "s%HOSTNAME%${PILER_HOSTNAME}%g" -e "s%MYSQL_PASSWORD%${MYSQL_PILER_PASSWORD}%g" "$CONFIG_SITE_PHP"

   if [[ $MULTITENANCY -eq 1 ]]; then
      sed -i "s%\$config\\['MULTITENANCY'\\] = 0%\$config\\['MULTITENANCY'\\] = 1%" "$CONFIG_SITE_PHP"
   fi

   {
      echo "\$config['SERVER_ID'] = $SERVER_ID;"
      echo "\$config['USE_SMTP_GATEWAY'] = $USE_SMTP_GATEWAY;"
      echo "\$config['SPHINX_VERSION'] = 331;"
   } >> "$CONFIG_SITE_PHP"

   if [[ "$SPHINX_WORKER_LISTEN_ADDRESS" ]]; then
      echo "\$config['SPHINX_WORKER_LISTEN_ADDRESS'] = '$SPHINX_WORKER_LISTEN_ADDRESS';" >> "$CONFIG_SITE_PHP"
   fi

   if [[ $MULTINODES -eq 1 ]]; then
      sed -i "s%\$config\\['MULTINODES'\\] = 0%\$config\\['MULTINODES'\\] = 1%" "$CONFIG_SITE_PHP"

      echo "\$config['AUTH_CODE'] = '$AUTH_CODE';" >> "$CONFIG_SITE_PHP"
      echo "\$config['PRIMARY_MASTER'] = $PRIMARY_MASTER;" >> "$CONFIG_SITE_PHP"

      if test "$NODE_TYPE" = "MASTER"; then
         echo "\$config['NODE_TYPE'] = MASTER;" >> "$CONFIG_SITE_PHP"
      else
         echo "\$config['MASTER_NODE'] = '$MASTER_NODE';" >> "$CONFIG_SITE_PHP"
      fi
   else
      echo "\$config['ARCHIVE_HOST'] = '$PILER_HOSTNAME';" >> "$CONFIG_SITE_PHP"
   fi
}


save_node_type() {
   echo "$NODE_TYPE" > "/etc/piler/${NODE_TYPE}"
}

save_multinodes_settings() {
   if [[ $MULTINODES -eq 1 ]]; then
      touch /etc/piler/MULTINODES
   fi
}

init_db() {
   sed -e "s%MYSQL_HOSTNAME%$MYSQL_HOSTNAME%g" -e "s%MYSQL_DATABASE%$MYSQL_DATABASE%g" -e "s%MYSQL_USERNAME%$MYSQL_USERNAME%g" -e "s%MYSQL_PASSWORD%$MYSQL_PILER_PASSWORD%g" \
      /usr/share/piler/db-mysql-root.sql.in | mysql --defaults-file=/etc/piler/.my.cnf-root -h "$MYSQL_HOSTNAME"

   if [[ $ENCRYPT_MYSQL_DATA_AT_REST -eq 1 ]]; then
      sed 's/Engine=InnoDB/ENGINE=InnoDB ENCRYPTED=YES/ig' /usr/share/piler/db-mysql.sql | mysql --defaults-file=/etc/piler/.my.cnf -h "$MYSQL_HOSTNAME" "$MYSQL_DATABASE"
   else
      mysql --defaults-file=/etc/piler/.my.cnf -h "$MYSQL_HOSTNAME" "$MYSQL_DATABASE" < /usr/share/piler/db-mysql.sql
   fi
}


get_the_licence() {
   echo "Get the license file, and copy it to /etc/piler/piler.lic"
}


add_systemd_services() {
   pushd /etc/systemd/system

   ln -sf /usr/libexec/piler/piler.service .
   ln -sf /usr/libexec/piler/piler-smtp.service .
   ln -sf /usr/libexec/piler/pilersearch.service .
   ln -sf /usr/libexec/piler/tika.service .

   popd

   systemctl daemon-reload

   systemctl enable piler
   systemctl enable piler-smtp
   systemctl enable pilersearch
   systemctl enable tika
}


setup_traefik() {
   wget -O /etc/systemd/system/traefik.service "${DOWNLOAD_URL}/generic-local/traefik.service"

   mkdir -p /usr/local/etc/traefik
   touch /usr/local/etc/traefik/acme.json
   chmod 600 /usr/local/etc/traefik/acme.json
   chown www-data:www-data /usr/local/etc/traefik/acme.json

   cat > /usr/local/etc/traefik/traefik.yaml << TRAEFIK
log:
  level: INFO

entryPoints:
  web:
    address: "1.2.3.4:80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: "1.2.3.4:443"

providers:
  file:
    filename: "/usr/local/etc/traefik/traefik.yaml"

certificatesResolvers:
  le:
    acme:
      storage: "/usr/local/etc/traefik/acme.json"
      email: admin@$PILER_HOSTNAME
      httpChallenge:
        entryPoint: web

tls:
  options:
    default:
      minVersion: VersionTLS13

http:
  middlewares:
    piler_headers:
      headers:
        customResponseHeaders:
          Server: ""
          Strict-Transport-Security: "max-age=31536000"
          X-Content-Type-Optionsi: "nosniff"
          Referrer-Policy: "same-origin"
  routers:
    master:
      rule: "Host(\`$PILER_HOSTNAME\`)"
      service: www
      middlewares:
        - "piler_headers"
      tls:
        certResolver: le
  services:
    www:
      loadBalancer:
        servers:
        - url: "http://127.0.0.1:80/"
TRAEFIK
}


create_default_tenant() {
   local PILERHOME=/var/piler
   local CUSTOMERID="piler"
   local SERVERID
   local sphinxdir="manticore"

   SERVERID=$(printf "%02x" "$SERVER_ID")

   echo "creating default tenant"

   if [[ ! -d "${PILERHOME}/store/${SERVERID}/${CUSTOMERID}" ]]; then
      mkdir -p "${PILERHOME}/store/${SERVERID}/${CUSTOMERID}"
      mkdir -p "${PILERHOME}/astore/${SERVERID}/${CUSTOMERID}"
      chown -R "${PILER_USER}:${PILER_USER}" "${PILERHOME}/store"
      chown -R "${PILER_USER}:${PILER_USER}" "${PILERHOME}/astore"
   fi

   if [[ ! -d "${PILERHOME}/${sphinxdir}/${CUSTOMERID}" ]]; then
      mkdir -p "${PILERHOME}/${sphinxdir}/${CUSTOMERID}"
      chown "${PILER_USER}:${PILER_USER}" "${PILERHOME}/${sphinxdir}/${CUSTOMERID}"
      chmod 700 "${PILERHOME}/${sphinxdir}/${CUSTOMERID}"

      echo "creating index files"

      echo main1 > "${PILERHOME}/${sphinxdir}/${CUSTOMERID}/MAIN"

      [[ -f "/etc/piler/MASTER" ]] || indexer --quiet --config /etc/piler/manticore.conf \
                                                 "${CUSTOMERID}_main1" \
                                                 "${CUSTOMERID}_dailydelta1" \
                                                 "${CUSTOMERID}_delta1" \
                                                 "${CUSTOMERID}_tag1" \
                                                 "${CUSTOMERID}_note1"
   fi

}


install_prerequisites

start_mysql

install_piler

create_my_cnf "root" "${MYSQL_ROOT_PASSWORD}" /etc/piler/.my.cnf-root
create_my_cnf "piler" "${MYSQL_PILER_PASSWORD}" /etc/piler/.my.cnf

fix_config_site_php

if [[ "$NODE_TYPE" == "WORKER" && ! -f .dockerenv ]]; then add_systemd_services; fi


if [ ! -f /etc/piler/piler-nginx.conf ]; then
   sed -e "s%HOSTNAME%$PILER_HOSTNAME%g" -e "s%PHP_FPM_SOCKET%$PHP_FPM_SOCKET%g" /etc/piler/piler-nginx.conf.dist > /etc/piler/piler-nginx.conf
   nginx -t
   nginx -s reload
fi

if [ ! -f /etc/piler/piler.conf ]; then
   sed -e "s/verystrongpassword/$MYSQL_PILER_PASSWORD/g" -e "s/piler.yourdomain.com/$PILER_HOSTNAME/g" /etc/piler/piler.conf.dist > /etc/piler/piler.conf
   chmod 600 /etc/piler/piler.conf
   chown $PILER_USER:$PILER_USER /etc/piler/piler.conf
fi


if [[ "$NODE_TYPE" == WORKER || $PRIMARY_MASTER -eq 1 ]]; then
   init_db
fi

save_node_type
save_multinodes_settings

[[ ! -d /var/run/piler ]] || mkdir -p /var/run/piler

systemctl start pilersearch
systemctl start tika

[[ $MULTITENANCY -eq 1 ]] || create_default_tenant

setup_traefik

get_the_licence
