#!/bin/bash -x

# source the debconf library
if [ -e "/usr/share/debconf/confmodule" ]; then
    . /usr/share/debconf/confmodule
else
    echo "debconf must be installed. Exiting."
    exit 1
fi

TOMCAT=tomcat9
TOMCAT_USER=tomcat
TOMCAT_HOME=/var/lib/${TOMCAT}
APACHE_CONF=/etc/apache2
JK_CONF=metacat_jk.conf
METACAT_PROXY=metacat_proxy

SYSCTL_CONF=/etc/sysctl.conf

PG=postgresql
PG_USER=postgres

D1_LOG_DIR=/var/log/dataone
if [ ! -e ${D1_LOG_DIR} ]; then
    mkdir -p ${D1_LOG_DIR}
    chown ${TOMCAT_USER}:${TOMCAT_USER} ${D1_LOG_DIR}
fi

# functions to echo to STDERR or the install log instead of STDOUT
logError () {
    echo -e "$@" 1>&2
}

log () {
    now=$(date "+%Y-%m-%d %H:%M:%S %Z: ")
    echo -e "${now}$@" >> ${D1_LOG_DIR}/dataone-cn-metacat.install.log
}

log "dataone-cn-metacat.postinst called"

ACTION=${1}
NEW_VERSION=${2}

LONG_DATE=`date +%Y%m%d%H%M%S`


if [ -e "/etc/postgresql/14/main" ]; then
    PG_CONF=/etc/postgresql/14/main
else
    PG_CONF=/etc/postgresql/10/main
fi

DB_USER=metacat
DB_PASS=metacat
SOURCE_DIR=/usr/share/metacat
SCRIPT_DIR=${SOURCE_DIR}/debian
METACAT_VAR=/var/metacat
METACAT_VAR_SUBDIRS=".metacat logs data inline-data documents expanded-archives temporary"
METACAT_CLIENT_TIMEOUT=300000

D1_CONF=/etc/dataone
ETC_CRON_DAILY_DIR=/etc/cron.daily
ETC_CRON_MONTHLY_DIR=/etc/cron.monthly

case "${ACTION}" in
    abort-remove)
    log "Removal aborted."
    ;;
    abort-upgrade)
    log "Upgrade aborted."
    ;;
    abort-deconfigure)
    log "Deconfigure aborted."
    ;;
    configure)
    log "Configure called."
    
    if [[ $(dpkg -s dataone-cn-metacat | grep Status | cut -d" " -f4) != "installed" ]]; then
    
        ###############################################################################
        # Parse node.properties file for various needed parameters to set elsewhere
        ###############################################################################
        
        HAZELCAST_INTERFACE=""
        SPACER="        "
        db_get dataone-cn-os-core/cn.iplist
        IPLIST=(${RET})
        for ip in ${IPLIST[@]}
        do
            IP_XML_NODE="<interface>${ip}<\/interface>"
            HAZELCAST_INTERFACE=${HAZELCAST_INTERFACE}${IP_XML_NODE}'\n'${SPACER}
        done
        
        #replace the string <interface>127.0.0.1</interface> with the environment's iplist
        
        sed -i.bak --regexp-extended "s/<interface>127\.0\.0\.1<\/interface>/${HAZELCAST_INTERFACE}/;" ${D1_CONF}/storage/hazelcast.xml
        
        #<interface>127.0.0.1</interface>
		db_get dataone-cn-os-core/cn.nodeid
		NODE_ID=$RET

		db_get dataone-cn-os-core/cn.client.certificate.dir
		D1CLIENT_CERTIFICATE_DIRECTORY=$RET

		db_get dataone-cn-os-core/cn.client.key.dir
		D1CLIENT_KEY_DIRECTORY=$RET

		db_get dataone-cn-os-core/cn.client.certificate.filename
		D1CLIENT_CERTIFICATE_FILENAME=$RET

        D1ClIENT_CERTIFICATE=${D1CLIENT_KEY_DIRECTORY}'/'${D1CLIENT_CERTIFICATE_FILENAME}
        D1ClIENT_CERTIFICATE=${D1ClIENT_CERTIFICATE//\//\\\/}
        
        ###############################################################################
        # Prompt for Metacat replication properties
        ###############################################################################
        db_get dataone-cn-os-core/cn.replication.certificate.filename
        METACAT_REPLICATION_CERTIFICATE_FILENAME=${RET}
        METACAT_REPLICATION_CERTIFICATE=${D1CLIENT_CERTIFICATE_DIRECTORY}'/'${METACAT_REPLICATION_CERTIFICATE_FILENAME}
        METACAT_REPLICATION_CERTIFICATE=${METACAT_REPLICATION_CERTIFICATE//\//\\\/}
        
        db_get dataone-cn-os-core/cn.replication.privatekey.filename
        METACAT_REPLICATION_KEY_FILENAME=${RET}
        METACAT_REPLICATION_KEY=${D1CLIENT_KEY_DIRECTORY}'/'${METACAT_REPLICATION_KEY_FILENAME}
        METACAT_REPLICATION_KEY=${METACAT_REPLICATION_KEY//\//\\\/}
        
        ###############################################################################
        # Install metacat war file
        ###############################################################################
        
        ## Stop tomcat
        log "Stopping Tomcat"
        systemctl stop ${TOMCAT}
        
        ## backup the old war file
        if [ -e ${TOMCAT_HOME}/webapps/metacat.war.current ]
        then
          log "Backing up ${TOMCAT_HOME}/webapps/metacat.war to ${TOMCAT_HOME}/webapps/metacat.war.${LONG_DATE}"
          mv ${TOMCAT_HOME}/webapps/metacat.war.current ${TOMCAT_HOME}/webapps/metacat.war.${LONG_DATE}
        fi  
        
        ## remove the metacat application directory
        if [ -d ${TOMCAT_HOME}/webapps/metacat ]
        then
          log "Removing the old metacat application directories"
          rm -rf ${TOMCAT_HOME}/webapps/metacat
        fi 
        
        ## copy the new war file into the webapps directory
        log "copying new metacat.war file to ${TOMCAT_HOME}/webapps/metacat.war"
        cp ${SOURCE_DIR}/metacat.war ${TOMCAT_HOME}/webapps/metacat.war
        
        ## expand the war file
        CURR_DIR=`pwd`
        
        ## make metacat directory and extract metacat.war into it.
        log "Making metacat application directory: ${TOMCAT_HOME}/webapps/metacat"
        mkdir ${TOMCAT_HOME}/webapps/metacat
        cd ${TOMCAT_HOME}/webapps/metacat
        
        log "extracting metacat.war into ${TOMCAT_HOME}/webapps/metacat"
        jar -xvf ${TOMCAT_HOME}/webapps/metacat.war > /dev/null
        
        mv ${TOMCAT_HOME}/webapps/metacat.war ${TOMCAT_HOME}/webapps/metacat.war.current
        
        sleep 5

        ## replace the token HOSTNAME in the site file to a hostname as found in debian backend db
        db_get dataone-cn-os-core/cn.hostname
        HOSTNAME=$RET

        if [ -n "$HOSTNAME" ]
        then
                sed -i.bak --regexp-extended  "s/(server\.name=).*/\1${HOSTNAME}/;" ${TOMCAT_HOME}/webapps/metacat/WEB-INF/metacat.properties
        else
                log "HOSTNAME can not be set in ${TOMCAT_HOME}/webapps/metacat/WEB-INF/metacat.properties"
        fi
        
        # get the CN RR entry
        db_get dataone-cn-os-core/cn.router.hostname
        CN_ROUTER_HOSTNAME=${RET}
        
        # change a lot of properties for this configuration
        sed -i --regexp-extended "s/(application\.deployDir=).*/\1\/var\/lib\/${TOMCAT}\/webapps/;
                s/(server\.httpPort=).*/\1443/;
                s/(application\.backupDir=).*/\1\/var\/metacat\/\.metacat/;
                s/(application\.context=).*/\1metacat/;
                s/(application\.debugOutputFile=).*/\1\/var\/metacat\/temporary\/metacat.debug/;
                s/(application\.delimiteredOutputFile=).*/\1\/var\/metacat\/temporary\/metacat\.debug\.delimitered/;
                s/(auth\.class=).*/\1edu\.ucsb\.nceas\.metacat\.AuthLdap/;                
                s/(database\.user=).*/\1metacat/;
                s/(database\.password=).*/\1metacat/;
                s/(database\.type=).*/\1postgres/;
                s/(database\.driver=).*/\1org\.postgresql\.Driver/;
                s/(database\.adapter=).*/\1edu\.ucsb\.nceas\.dbadapter\.PostgresqlAdapter/;
                s/(auth\.administrators=).*/\1uid\=dataone\_cn\_metacat\,o\=DATAONE\,dc\=ecoinformatics\,dc\=org/;
                s/(replication\.logdir=).*/\1\/var\/metacat\/logs/;
                s/(replication\.certificate\.file=).*/\1${METACAT_REPLICATION_CERTIFICATE}/;
                s/(replication\.privatekey\.file=).*/\1${METACAT_REPLICATION_KEY}/;
                s/(replication\.privatekey\.password=).*/\1${METACAT_REPLICATION_KEY_PASSWORD}/;
                s/(replication\.client\.timeout=).*/\1${METACAT_CLIENT_TIMEOUT}/;
                s/(spatial\.regenerateCacheOnRestart=).*/\1false/;
                s/(spatial\.runSpatialOption=).*/\1false/;
                s/(replication\.timedreplication=).*/\1true/;
                s/(D1Client\.CN_URL=).*/\1https\:\/\/${CN_ROUTER_HOSTNAME}\/cn/;
                s/(D1Client\.certificate\.file=).*/\1${D1ClIENT_CERTIFICATE}/;
                s/(dataone\.nodeType=).*/\1cn/;
                s/(dataone\.nodeId=).*/\1${NODE_ID}/;
                s/(database\.usexmlindex=).*/\1false/;
                s/(dbquery\.enabledEngines=).*/\1solr/;
                s/(index\.regenerate\.failedObject=).*/\1false/;
                s/(index\.regenerate\.sincelastProcessDate=).*/\1false/;
                s/(#)(dataone\.hazelcast\.configFilePath=\/etc\/dataone\/storage\/hazelcast\.xml)/\2/;"\
                ${TOMCAT_HOME}/webapps/metacat/WEB-INF/metacat.properties
        
        # the CN has its own log4j configuration
        
        cp ${SCRIPT_DIR}/log4j2.properties ${TOMCAT_HOME}/webapps/metacat/WEB-INF/classes
        chown -R ${TOMCAT_USER}:${TOMCAT_USER} ${TOMCAT_HOME}/webapps/metacat
        log "cd to $CURR_DIR"
        cd $CURR_DIR
        
        # Ensure tomcat is in the ssl-cert group to read private keys
        usermod -a -G ssl-cert ${TOMCAT_USER}
        
        chmod -R  +x ${TOMCAT_HOME}/webapps/metacat/cgi-bin
        
        ###############################################################################
        # Create Metacat External File Space
        ###############################################################################
        
        ## Create the /var/metacat directory
        if [ ! -d ${METACAT_VAR} ]
        then
          log "Making Metacat utility directory: /var/metacat"
          mkdir ${METACAT_VAR}
        fi
        
        ## Change the ownership of the /var/metacat directory to be the tomcat user.
        log "changing ownership of /var/metacat to ${TOMCAT_USER}"
        chown -R ${TOMCAT_USER}:${TOMCAT_USER} ${METACAT_VAR}
        
        ## Create the dataone logging directory
        for SUBDIR in ${METACAT_VAR_SUBDIRS}
        do
            FULL_VAR_SUBDIR=${METACAT_VAR}/${SUBDIR}
            if [ ! -d ${FULL_VAR_SUBDIR} ]
            then
              log "Making Metacat application directory: ${FULL_VAR_SUBDIR}"
              mkdir ${FULL_VAR_SUBDIR}
              log "changing ownership of ${FULL_VAR_SUBDIR}  to ${TOMCAT_USER}"
              chown ${TOMCAT_USER}:${TOMCAT_USER} ${FULL_VAR_SUBDIR}
            fi
        done
        ###############################################################################
        # Configure Tomcat
        ###############################################################################
        # fix an issue that tomcat9 doesn't work with metacat admin page
        ln -s /usr/share/java/ecj.jar /var/lib/tomcat9/lib
        
        # Configure the tomcat server
        #cp ${SCRIPT_DIR}/server.xml ${TOMCAT_HOME}/conf/
        
        # Configure the context file
        cp ${SCRIPT_DIR}/metacat.xml ${TOMCAT_HOME}/conf/Catalina/localhost/
        
        # Add permissions needed by metacat and geoserver
        cp ${SCRIPT_DIR}/51metacat.policy ${TOMCAT_HOME}/conf/policy.d/
        
        # Add the tomcat service file
        cp ${SCRIPT_DIR}/${TOMCAT}.service /etc/systemd/system/.
        systemctl daemon-reload
        
        ###############################################################################
        # Configure Apache
        ###############################################################################
        
        ## Stop apache
        log "Stopping Apache"
        /etc/init.d/apache2 stop
        
        ## copy in metacat_proxy configuration file
        
        if [ -e ${APACHE_CONF}/conf-available/${METACAT_PROXY}.conf ]
        then 
          PROXY_DIFF=$(diff ${SCRIPT_DIR}/${METACAT_PROXY}.conf ${APACHE_CONF}/conf-available/${METACAT_PROXY}.conf)
          if [ "${PROXY_DIFF}" != "" ]; then
             if [ ! -e ${APACHE_CONF}/conf-available.bak ]
             then
	       mkdir ${APACHE_CONF}/conf-available.bak
             fi 
            log "Backing up ${APACHE_CONF}/conf-available/${METACAT_PROXY}.conf to ${APACHE_CONF}/conf-available.bak/${METACAT_PROXY}.conf.${LONG_DATE}"
            mv ${APACHE_CONF}/conf-available/${METACAT_PROXY}.conf ${APACHE_CONF}/conf-available.bak/${METACAT_PROXY}.conf.${LONG_DATE}
          fi
        fi
        log "Copying ${METACAT_PROXY}.conf file to ${APACHE_CONF}/conf-available/"
        cp ${SCRIPT_DIR}/${METACAT_PROXY}.conf ${APACHE_CONF}/conf-available/
        # enable the config
        a2enconf ${METACAT_PROXY}
        
        
        ## copy in jk mount configuration file
        
        if [ -e ${APACHE_CONF}/jk_mount/${JK_CONF} ]
        then 
          JK_DIFF=$(diff ${SCRIPT_DIR}/${JK_CONF} ${APACHE_CONF}/jk_mount/${JK_CONF})
          if [ "${JK_DIFF}" != "" ]; then
            log "Backing up ${APACHE_CONF}/jk_mount/${JK_CONF} to ${APACHE_CONF}/jk_mount/${JK_CONF}.${LONG_DATE}"
            mv ${APACHE_CONF}/jk_mount/${JK_CONF} ${APACHE_CONF}/jk_mount/${JK_CONF}.${LONG_DATE}
          fi
        fi
        log "Copying ${JK_CONF} site file to ${APACHE_CONF}/jk_mount/"
        cp ${SCRIPT_DIR}/${JK_CONF} ${APACHE_CONF}/jk_mount/
        
        
        ###############################################################################
        # Configure Postgres
        ###############################################################################
        
        ## modify pg_hba.conf
        PG_HBA_IS_MODIFIED=`grep "metacat metacat" ${PG_CONF}/pg_hba.conf`
        if [ "${PG_HBA_IS_MODIFIED}" == "" ]; then
          log "backing up ${PG_CONF}/pg_hba.conf to ${PG_CONF}/pg_hba.conf.bak"
          cp ${PG_CONF}/pg_hba.conf ${PG_CONF}/pg_hba.conf.bak
          chown postgres ${PG_CONF}/pg_hba.conf
          chgrp postgres ${PG_CONF}/pg_hba.conf
        
          log "appending 'host metacat metacat 127.0.0.1 255.255.255.255 password' to ${PG_CONF}/pg_hba.conf"
          echo "host metacat metacat 127.0.0.1 255.255.255.255 password" >> ${PG_CONF}/pg_hba.conf
          
          log "commenting out the lines with the authorization method scram-sha-256 in ${PG_CONF}/pg_hba.conf"
          sed -i '/^[^#].*scram-sha-256/ s/^/#/' ${PG_CONF}/pg_hba.conf
        fi
        
        ## postgresql.conf  max_connections = 400
        let MAX_CONNECTIONS=$(egrep "max_connections *=" ${PG_CONF}/postgresql.conf | cut -d# -f1 | cut -d= -f2 | tr -d " ")
        if [ ${MAX_CONNECTIONS} -ne 400 ]; then
            sed -i.bak  's/\(max_connections\s*\=\s*\).*/\1 400/;' ${PG_CONF}/postgresql.conf
        fi
        
        ## postgresql.conf shared_buffers = 2GB
        SHARED_BUFFERS=$(egrep "shared_buffers *=" ${PG_CONF}/postgresql.conf | cut -d= -f2 | cut -d# -f1 | tr -d " ")
        if [[ "" != "2048MB" ]]; then
            sed -i.bak  's/\(shared_buffers\s*\=\s*\).*/\1 2048MB/;' ${PG_CONF}/postgresql.conf
        fi
        
        ## Get the amount of ram 
        MEMORY_SIZE=$(free -m | grep 'Mem' | sed 's/^Mem:\s*\([0-9]*\).*/\1/')
        
        ## Set the effective_cache_size to half of available ram
        EFFECTIVE_CACHE_SIZE=$(expr ${MEMORY_SIZE} / 2)
        sed -i.bak "s/^[# ]*effective_cache_size\s*=.*/effective_cache_size = ${EFFECTIVE_CACHE_SIZE}MB/" ${PG_CONF}/postgresql.conf
        
        ## Set work_mem to 1/3 the amount of RAM / the number of connections except 
        ## in case of small RAM sizes (<4000MB) where it will 1/5 instead of 1/3
        if [[ ${MEMORY_SIZE} -lt 4000 ]]; then
           WORK_MEM_FACTOR=5
        else
           WORK_MEM_FACTOR=3
        fi
        
        MAX_CONNECTIONS=$(egrep "max_connections *=" ${PG_CONF}/postgresql.conf | cut -d# -f1 | cut -d= -f2 | tr -d " ")
        WORK_MEM=$(expr ${MEMORY_SIZE} / ${WORK_MEM_FACTOR} / ${MAX_CONNECTIONS})
        sed -i.bak "s/^[# ]*work_mem\s*=.*/work_mem = ${WORK_MEM}MB/" ${PG_CONF}/postgresql.conf

        ## http://www.postgresql.org/docs/9.1/static/kernel-resources.html
        ## With postgres 9.3 and higher the required amount of 
        ## of shared memory is lower, once upgrade to ubuntu 14.04
        ## the shared memory problem should be re-evaluated
        ## http://www.postgresql.org/docs/9.3/static/kernel-resources.html  

        ## with higher memory requirements for postgresql, increase kernel.shmmax to 3GB
        if  (egrep -q 'kernel\.shmmax=' ${SYSCTL_CONF}); then          
			SHMMAX=$(egrep "kernel\.shmmax=" ${SYSCTL_CONF}  | cut -d= -f2 | cut -d# -f1 | tr -d " ")
			if [[ "${SHMMAX}" != "3221225472" ]]; then
				sed -i.bak  's/.*\(kernel\.shmmax\)\=.*/\1=3221225472/;' ${SYSCTL_CONF}
				sysctl -w kernel.shmmax=3221225472
			fi
		else
			echo "kernel.shmmax=3221225472" >> ${SYSCTL_CONF}
			sysctl -p
		fi

        ## create metacat schema and user
        log "Creating metacat database schema"
        su ${PG_USER} -c "createdb metacat"
        
        log "Creating metacat user" 
        su ${PG_USER} -c "psql -c \"CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}'\""
        
        ## Restart the postgres db
        log "Restarting postgres database"
        /etc/init.d/${PG} restart
        
        
        
        ######### Update DateONE Version Info Doc  #############
        if [ -e /usr/share/dataone-cn-version-tool/dataone-cn-version-tool.jar ] ; then
           java -jar /usr/share/dataone-cn-version-tool/dataone-cn-version-tool.jar -F/usr/share/dataone-cn-version-tool/version-tool.properties -html > /var/www/cn-version.html
        fi
        
        ###############################################################################
        # Start Apache and Tomcat
        ###############################################################################
        
        ## Start Apache
        /etc/init.d/apache2 start
        
        ## Start Tomcat
        log "starting Tomcat server"
        
        systemctl start ${TOMCAT}
        

		for IP in ${IPLIST[@]}
			do
				#open up the correct port for hazelcast
				log "Added 'ufw allow to any port 5701 from ${IP}' rule"
				ufw allow to any port 5701 from ${IP}
			done

		cp ${SCRIPT_DIR}/pgsql-daily ${ETC_CRON_DAILY_DIR}/pgsql
		cp ${SCRIPT_DIR}/pgsql-monthly ${ETC_CRON_MONTHLY_DIR}/pgsql
		chmod 755 ${ETC_CRON_DAILY_DIR}/pgsql
		chmod 755 ${ETC_CRON_MONTHLY_DIR}/pgsql
        db_stop
    else
        log "Already configured, skipping posinst"
    fi
    ;;
esac

exit 0