#!/bin/bash

set -e

## Exit codes

EXIT_VALIDATION_ERROR=1
EXIT_ERROR=2
EXIT_ALREADY_CONFIGURED=3


# get product name, default: SUSE Manager
IFS=" = "
DEFAULT_RHN_CONF="/usr/share/rhn/config-defaults/rhn.conf"

if [ -f "$DEFAULT_RHN_CONF" ]; then
    while read -r name value
    do
        if [ "$name" == "product_name" ]; then
            PRODUCT_NAME=$value
        fi
    done < $DEFAULT_RHN_CONF
fi
if [ ! -n "$PRODUCT_NAME" ]; then
    PRODUCT_NAME="SUSE Manager"
fi

if [ ! $UID -eq 0 ]; then
    echo "You need to be superuser (root) to run this script!"
    exit $EXIT_VALIDATION_ERROR
fi

if [[ -n "$TZ" ]]; then
    rm -f /etc/localtime
    ln -s /usr/share/zoneinfo/$TZ /etc/localtime
fi

TMPDIR="/var/spacewalk/tmp"

MANAGER_COMPLETE="/root/.MANAGER_SETUP_COMPLETE"

REPORT_DB_CA_CERT="/etc/pki/trust/anchors/LOCAL-RHN-ORG-TRUSTED-SSL-CERT"

function help() {
    echo "
Usage: $0 [OPTION]
helper script to do migration or setup of $PRODUCT_NAME

  -h             this help screen
"
}

ask_input() {
    # Set using an env variable or to an empty string.
    VARIABLE=$1
    if [ -z ${!VARIABLE+x} ]; then
        declare $VARIABLE=
    fi
}

setup_mail () {
    postconf -e myhostname=$HOSTNAME
    # No need to enable postfix: it already is
}

db_schema_exists() {
    DBNAME=$1
    TABLE="web_customer"
    if test "$DBNAME" == "$REPORT_DB_NAME"; then
        TABLE="systemhistory"
    fi

    # Assumption, if web_customer table exists then schema exists:
    QUERY="SELECT tablename from pg_tables where schemaname='public' and tablename='$TABLE';"
    EXISTS=$(echo "$QUERY" | (PGPASSWORD=$MANAGER_PASS psql -t -U $MANAGER_USER -h $MANAGER_DB_HOST $DBNAME))
    if [ "x$EXISTS" == "x $TABLE" ] ; then
        return 0
    else
        return 1
    fi
}

run_sql() {
    local DBNAME=$1
    shift 
    local USER=$MANAGER_USER
    local PASS=$MANAGER_PASS
    local HOST=$MANAGER_DB_HOST
    local PORT=$MANAGER_DB_PORT
    if test "$DBNAME" == "$REPORT_DB_NAME"; then
        USER=$REPORT_DB_USER
        PASS=$REPORT_DB_PASS
        HOST=$REPORT_DB_HOST
        PORT=$REPORT_DB_PORT
    fi

    PGPASSWORD=$PASS psql -U $USER -h $HOST -p $PORT -d $DBNAME -v ON_STOP_ERROR=ON "$@"
}

db_clear() {
    for schema in `echo "SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname NOT LIKE 'information_schema';" | run_sql $MANAGER_DB_NAME -t`;
    do
        echo "DROP SCHEMA IF EXISTS $schema CASCADE;" | run_sql $MANAGER_DB_NAME;
    done
}

setup_db_postgres() {
    if db_schema_exists $MANAGER_DB_NAME; then
        echo "Clearing the database"
        db_clear
    fi

    echo "Populating the database"
    PGPASSWORD=$MANAGER_PASS PGOPTIONS='--client-min-messages=error -c standard_conforming_strings=on' \
        psql -U $MANAGER_USER -p $MANAGER_DB_PORT -d $MANAGER_DB_NAME -h $MANAGER_DB_HOST -v ON_STOP_ERROR=ON -q -b </usr/share/susemanager/db/postgres/main.sql

    # Some tools in the setup call spacewalk-sql and require the db to be defined in rhn.conf at an early stage
    cat >>/etc/rhn/rhn.conf <<EOF
db_backend=postgresql
db_host=$MANAGER_DB_HOST
db_port=$MANAGER_DB_PORT
db_name=$MANAGER_DB_NAME
db_user=$MANAGER_USER
db_password=$MANAGER_PASS
db_ssl_enabled=
EOF

    # Can go away with ISSv1
    cat >>/var/lib/rhn/rhn-satellite-prep/satellite-local-rules.conf <<EOF
db_backend=postgresql
db_host=$MANAGER_DB_HOST
db_port=$MANAGER_DB_PORT
db_name=$MANAGER_DB_NAME
db_user=$MANAGER_USER
db_password=$MANAGER_PASS
db_ssl_enabled=
EOF
}

report_db_clear() {
    echo "Clearing the report database"
    for schema in `echo "SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname NOT LIKE 'information_schema';" | run_sql $REPORT_DB_NAME -t`;
    do
        echo "DROP SCHEMA IF EXISTS $schema CASCADE;" | run_sql $REPORT_DB_NAME;
    done
    echo "Report database cleared"
}

setup_reportdb() {
    if db_schema_exists $REPORT_DB_NAME; then
        report_db_clear
    fi

    # Some tools in the setup call spacewalk-sql and require the db to be defined in rhn.conf at an early stage
    cat >>/etc/rhn/rhn.conf <<EOF
report_db_backend=postgresql
report_db_host=$REPORT_DB_HOST
report_db_port=$REPORT_DB_PORT
report_db_name=$REPORT_DB_NAME
report_db_user=$REPORT_DB_USER
report_db_password=$REPORT_DB_PASS
report_db_ssl_enabled=1
report_db_sslrootcert=$REPORT_DB_CA_CERT
EOF

    # Can go away with ISSv1
    cat >>/var/lib/rhn/rhn-satellite-prep/satellite-local-rules.conf <<EOF
report_db_backend=postgresql
report_db_host=$REPORT_DB_HOST
report_db_port=$REPORT_DB_PORT
report_db_name=$REPORT_DB_NAME
report_db_user=$REPORT_DB_USER
report_db_password=$REPORT_DB_PASS
report_db_ssl_enabled=1
report_db_sslrootcert=$REPORT_DB_CA_CERT
EOF

    echo "Populating the report database"
    run_sql $REPORT_DB_NAME </usr/share/susemanager/db/reportdb/main.sql
    echo "Report database set up and populated"
}

check_re_install() {
if [ -f $MANAGER_COMPLETE ]; then
    echo "$PRODUCT_NAME is already set up. Exit." >&2
    exit $EXIT_ALREADY_CONFIGURED
fi
}

setup_spacewalk() {
    # Deploy the SSL certificates
    if [ "$NO_SSL" == "Y" ]; then
        /usr/bin/spacewalk-setup-httpd --no-ssl
    else
        /usr/bin/spacewalk-setup-httpd
    fi
    /usr/sbin/update-ca-certificates
    /usr/bin/rhn-ssl-dbstore --ca-cert /etc/pki/trust/anchors/LOCAL-RHN-ORG-TRUSTED-SSL-CERT

    if [ ! -f /srv/susemanager/salt/images/rhn-org-trusted-ssl-cert-osimage-1.0-1.noarch.rpm ]; then
        /usr/sbin/mgr-package-rpm-certificate-osimage
    fi

    echo "admin-email = $MANAGER_ADMIN_EMAIL
ssl-config-sslvhost = Y
db-backend=postgresql
db-user=$MANAGER_USER
db-password=$MANAGER_PASS
db-name=$MANAGER_DB_NAME
db-host=$MANAGER_DB_HOST
db-port=$MANAGER_DB_PORT
db-ca-cert=$MANAGER_DB_CA_CERT
report-db-ca-cert=$REPORT_DB_CA_CERT
externaldb-provider=$EXTERNALDB_PROVIDER
report-db-backend=postgresql
report-db-name=$REPORT_DB_NAME
report-db-host=$REPORT_DB_HOST
report-db-port=$REPORT_DB_PORT
report-db-user=$REPORT_DB_USER
report-db-password=$REPORT_DB_PASS
enable-tftp=$MANAGER_ENABLE_TFTP
product_name=$PRODUCT_NAME
hostname=$HOSTNAME
" > /root/spacewalk-answers

    if [ -n "$SCC_USER" ]; then
        echo "scc-user = $SCC_USER
scc-pass = $SCC_PASS
" >> /root/spacewalk-answers
        PARAM_CC="--scc"
    elif [ -n "$ISS_PARENT" ]; then
        PARAM_CC="--disconnected"
    fi

    if [ "$NO_SSL" == "Y" ]; then
        echo "no-ssl = Y
" >>/root/spacewalk-answers
        sed '/ssl/Id' -i /etc/apache2/conf.d/zz-spacewalk-www.conf
        echo "server.no_ssl = 1" >>/etc/rhn/rhn.conf
        sed '/<IfDefine SSL/,/<\/IfDefine SSL/d' -i /etc/apache2/listen.conf
    fi

    /usr/bin/spacewalk-setup --clear-db $PARAM_CC --answer-file=/root/spacewalk-answers
    SWRET=$?
    if [ "x" = "x$MANAGER_MAIL_FROM" ]; then
        MANAGER_MAIL_FROM="$PRODUCT_NAME ($HOSTNAME) <root@$HOSTNAME>"
    fi
    if ! grep "^web.default_mail_from" /etc/rhn/rhn.conf > /dev/null; then
        echo "web.default_mail_from = $MANAGER_MAIL_FROM" >> /etc/rhn/rhn.conf
    fi

    # The CA needs to be added to the database for Kickstart use.
    /usr/bin/rhn-ssl-dbstore --ca-cert /etc/pki/trust/anchors/LOCAL-RHN-ORG-TRUSTED-SSL-CERT

    # rm /root/spacewalk-answers
    if [ "$SWRET" != "0" ]; then
        echo "ERROR: spacewalk-setup failed" >&2
        exit $EXIT_ERROR
    fi
}

do_setup() {
    # ask for the needed values if the setup_env file does not exist
    ask_input MANAGER_USER
    ask_input MANAGER_PASS
    ask_input MANAGER_ADMIN_EMAIL
    ask_input MANAGER_DB_NAME
    ask_input MANAGER_DB_HOST
    ask_input MANAGER_DB_PORT
    ask_input MANAGER_DB_CA_CERT
    ask_input MANAGER_ENABLE_TFTP
    ask_input EXTERNALDB_PROVIDER
    ask_input SCC_USER
    ask_input SCC_PASS
    ask_input ISS_PARENT
    ask_input REPORT_DB_NAME
    ask_input REPORT_DB_HOST
    ask_input REPORT_DB_PORT
    ask_input REPORT_DB_USER
    ask_input REPORT_DB_PASS
    ask_input REPORT_DB_CA_CERT
    ask_input UYUNI_FQDN
    if [ -z "$MANAGER_DB_NAME" ]; then
        MANAGER_DB_NAME="susemanager"
    fi
    if [ -z "$REPORT_DB_NAME" ]; then
        REPORT_DB_NAME="reportdb"
    fi
    if [ -z "$REPORT_DB_PORT" ]; then
        REPORT_DB_PORT="5432"
    fi
    if [ -z "$REPORT_DB_USER" ]; then
        REPORT_DB_USER="pythia_susemanager"
    fi

    if [ -z "$NO_SSL" ]; then
        NO_SSL=
    fi
    if [ -n "$UYUNI_FQDN" ]; then
        HOSTNAME=$UYUNI_FQDN
    fi

    check_re_install
    echo "Do not delete this file unless you know what you are doing!" > $MANAGER_COMPLETE
    setup_mail
    setup_db_postgres
    setup_reportdb

    setup_spacewalk

    # In the container case, we have the MIRROR_PATH environment variable at setup
    if [ -n "$MIRROR_PATH" ]; then
        echo "server.susemanager.fromdir = $MIRROR_PATH" >> /etc/rhn/rhn.conf
    fi

    if [ -n "$ISS_PARENT" ]; then
        local certname=`echo "MASTER-$ISS_PARENT-TRUSTED-SSL-CERT" | sed 's/\./_/g'`
        curl -s -S -o /usr/share/rhn/$certname "http://$ISS_PARENT/pub/RHN-ORG-TRUSTED-SSL-CERT"
        if [ -e /usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT ] && \
           cmp -s /usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT /usr/share/rhn/$certname ; then
            # equal - use it
            rm -f /usr/share/rhn/$certname
            certname=RHN-ORG-TRUSTED-SSL-CERT
        else
            /usr/share/rhn/certs/update-ca-cert-trust.sh $certname
        fi
        echo "
        INSERT INTO rhnISSMaster (id, label, is_current_master, ca_cert)
        VALUES (sequence_nextval('rhn_issmaster_seq'), '$ISS_PARENT', 'Y', '/usr/share/rhn/$certname');
        " | spacewalk-sql -
    fi
}

####################################################
# Start
####################################################

PROGRAM="$0"

while [ -n "$1" ]
do
    p="$1"

    case "$p" in
    -h)
        help
       ;;
    *)
       echo
       echo "Option \"$p\" is not recognized. Type \"$PROGRAM -h\" for help."
       echo
       exit $EXIT_VALIDATION_ERROR
       ;;
    esac

    shift
done

do_setup

systemctl --quiet enable spacewalk-diskcheck.timer 2>&1

# vim: set expandtab:
