#!/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=1
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:-}"
ENCRYPTION_KEY="$( openssl rand -base64 24 )"
PHP_FPM_SOCKET="/run/php/php8.3-fpm.sock"
DISTRO="noble"
PILER_VERSION="1.8.2"
RT=${RT:-1}
ARCH="${ARCH:-amd64}"
DYNAMIC_CONFIG=${DYNAMIC_CONFIG:-1}
MANTICORE_HOST="127.0.0.1"
MYSQL_HOSTNAME="localhost"
MYSQL_DATABASE="piler"
MYSQL_USERNAME="piler"

TIKA_VERSION="2.9.2"
TRAEFIK_VERSION="v3.0.1"
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}_${ARCH}.deb"
PILER_USER="piler"
PILER_CONF="/etc/piler/piler.conf"
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 manticore-extra
   apt-get -y --no-install-recommends install wget rsyslog openssl sysstat unzip php8.3-cli php8.3-cgi php8.3-mysql php8.3-fpm php8.3-zip php8.3-ldap php8.3-gd php8.3-curl php8.3-xml php8.3-mbstring php-memcached nginx sudo libtre5 libzip4t64 zip libmariadb-dev mariadb-server cron openjdk-21-jre memcached python3-pip python3-mysqldb netcat-openbsd jq wkhtmltopdf
   pip3 install --break-system-packages minio==7.1.12 imapclient==2.2.0 pycryptodome==3.20.0
   wget "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_linux_${ARCH}.tar.gz"
   tar zxvf "traefik_${TRAEFIK_VERSION}_linux_${ARCH}.tar.gz" traefik
   chown root:root traefik
   chmod 755 traefik
   mv traefik /usr/local/bin
   setcap cap_net_bind_service+ep /usr/local/bin/traefik
   systemctl stop manticore
   echo "www-data ALL=NOPASSWD: /usr/bin/systemctl restart piler" >> /etc/sudoers
}


setup_mysql_encryption() {
   local s
   local encrypt_cfg_dir="/etc/mysql/encrypt"

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

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

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

plugin_load_add = file_key_management
loose_file_key_management_filename = ${encrypt_cfg_dir}/keyfile.enc
loose_file_key_management_filekey = FILE:${encrypt_cfg_dir}/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 mariadb 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
      if [[ $RT -eq 1 ]]; then
         sed -i 's/.*indexer.*\.sh/###/g' /usr/share/piler/piler.cron
      fi
   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" "https://dlcdn.apache.org/tika/${TIKA_VERSION}/tika-server-standard-${TIKA_VERSION}.jar"

   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

   if [[ $DYNAMIC_CONFIG -eq 1 ]]; then
      touch /etc/piler/MANTICORE_DYNAMIC
   fi

   echo "piler ALL=NOPASSWD: /usr/bin/systemctl restart pilersearch" >> /etc/sudoers

   chgrp www-data /var/piler/export
}


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['ENABLE_MEMCACHED'] = 1;"
      echo "\$config['TIMEZONE'] = 'Europe/Budapest';"
      echo "\$config['ENCRYPTION_KEY'] = '$ENCRYPTION_KEY';"
   } >> "$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

   if [[ $RT -eq 1 ]]; then
      echo "\$config['RT_INDEX'] = 1;" >> "$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:
  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
      tlsChallenge: {}

tls:
  options:
    default:
      minVersion: VersionTLS13

http:
  middlewares:
    piler_headers:
      headers:
        customResponseHeaders:
          Server: ""
          Strict-Transport-Security: "max-age=31536000; includeSubDomains"
          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
      if [[ $DYNAMIC_CONFIG -eq 1 ]]; then
            if [[ -f /etc/piler/MASTER ]]; then
               if ! mysql -N -h "$MANTICORE_HOST" -P9306 <<< "SHOW INDEX ${CUSTOMERID} STATUS" 2>/dev/null; then
                  /usr/libexec/piler/print-master-node-index.php "$CUSTOMERID" | mysql -h "$MANTICORE_HOST" -P9306
               fi
            else
               sed "s/CUSTOMERID/${CUSTOMERID}/g" /etc/piler/manticore.sql | mysql -h "$MANTICORE_HOST" -P9306
            fi
            logger -i -t piler/create-customer -p mail.info <<< "Created index for ${CUSTOMERID}"
      else
         mkdir -p "${PILERHOME}/${sphinxdir}/${CUSTOMERID}"
         chown "${PILER_USER}:${PILER_USER}" "${PILERHOME}/${sphinxdir}/${CUSTOMERID}"
         chmod 700 "${PILERHOME}/${sphinxdir}/${CUSTOMERID}"

         if [[ $RT -eq 0 ]]; then
            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"; chown -R "${PILER_USER}:${PILER_USER}" /var/piler/manticore; }
         fi
      fi
   fi
}

write_goss_vars() {
cat >/etc/piler/vars.yaml <<EOF
piler_host: "$PILER_HOSTNAME"
piler_url: "https://$PILER_HOSTNAME"
nodetype: "$NODE_TYPE"
multitenancy: $MULTITENANCY
multinodes: $MULTINODES
tika_url: "http://localhost:9998/tika"
memcached_host: "127.0.0.1"
EOF
}


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 "$PILER_CONF" ]]; then
   sed -e "s/verystrongpassword/$MYSQL_PILER_PASSWORD/g" -e "s/piler.yourdomain.com/$PILER_HOSTNAME/g" "${PILER_CONF}.dist" > "$PILER_CONF"
   chmod 600 "$PILER_CONF"
   chown $PILER_USER:$PILER_USER "$PILER_CONF"

   sed -i "s%crypt_key=.*%crypt_key=$ENCRYPTION_KEY%" "$PILER_CONF"

   if [[ $RT -eq 1 ]]; then
      sed -i "s%rtindex=.*%rtindex=1%" "$PILER_CONF"
   fi
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

write_goss_vars

get_the_licence
