#!/usr/bin/env bash
set -xe

# Assumes we've already been untarred

# Specify options for apt.
APT_OPTIONS="${APT_OPTIONS:-}"
# Install additional packages using apt.
ADDITIONAL_PACKAGES=${ADDITIONAL_PACKAGES:-}
# Deployment type is almost always voyager.
DEPLOYMENT_TYPE="${DEPLOYMENT_TYPE:-voyager}"
# Comma-separated list of puppet manifests to install.  default is
# zulip::voyager for an all-in-one system or zulip::dockervoyager for
# Docker.  Use e.g. zulip::app_frontend for a Zulip frontend server.
PUPPET_CLASSES="${PUPPET_CLASSES:-zulip::voyager}"
VIRTUALENV_NEEDED="${VIRTUALENV_NEEDED:-yes}"

# setup-apt-repo does an `apt-get update`
/root/zulip/scripts/lib/setup-apt-repo

apt-get -y dist-upgrade $APT_OPTIONS
apt-get install -y puppet git python python-six crudini $ADDITIONAL_PACKAGES

# Create and activate a virtualenv
if [ "$VIRTUALENV_NEEDED" = "yes" ]; then
    /root/zulip/scripts/lib/create-production-venv /root/zulip/zulip-venv
fi

# puppet apply
mkdir -p /etc/zulip
(
    echo -e "[machine]\npuppet_classes = $PUPPET_CLASSES\ndeploy_type = $DEPLOYMENT_TYPE";
    if [ -n "$TRAVIS" ]; then
        echo -e "\n[rabbitmq]\nnodename = zulip@localhost"
    fi
) > /etc/zulip/zulip.conf
/root/zulip/scripts/zulip-puppet-apply -f

# Detect which features were selected for the below
set +e
[ -e "/etc/init.d/camo" ]; has_camo=$?
[ -e "/etc/init.d/nginx" ]; has_nginx=$?
[ -e "/etc/supervisor/conf.d/zulip.conf" ]; has_appserver=$?
[ -e "/etc/cron.d/rabbitmq-numconsumers" ]; has_rabbit=$?
[ -e "/etc/init.d/postgresql" ]; has_postgres=$?
set -e

# Docker service setup is done in the docker config, not here
if [ "$DEPLOYMENT_TYPE" = "dockervoyager" ]; then
    has_camo=1
    has_nginx=1
    has_appserver=1
    has_rabbit=1
    has_postgres=1
fi

# These server restarting bits should be moveable into puppet-land, ideally
apt-get -y upgrade

if [ "$has_nginx" = 0 ]; then
    # Check nginx was configured properly now that we've installed it.
    # Most common failure mode is certs not having been installed.
    nginx -t
    service nginx restart
fi

if [ "$has_appserver" = 0 ]; then
    /root/zulip/scripts/setup/generate_secrets.py --production
    cp -a /root/zulip/zproject/prod_settings_template.py /etc/zulip/settings.py
    ln -nsf /etc/zulip/settings.py /root/zulip/zproject/prod_settings.py
fi

# Restart camo since generate_secrets.py likely replaced its secret key
if [ "$has_camo" = 0 ] && [ -z "$TRAVIS" ]; then
    # We don't run this in Travis CI due to a weird hang bug
    service camo restart
fi

if [ "$has_rabbit" = 0 ]; then
    if ! rabbitmqctl status >/dev/null; then
        set +x
        echo; echo "RabbitMQ seems to not have started properly after the installation process."
        echo "Often, this can be caused by misconfigured /etc/hosts in virtualized environments"
        echo "See https://github.com/zulip/zulip/issues/53#issuecomment-143805121"
        echo "for more information"
        echo
        set -x
        exit 1
    fi
    /root/zulip/scripts/setup/configure-rabbitmq
fi

if [ "$has_postgres" = 0 ]; then
    /root/zulip/scripts/setup/postgres-init-db
fi

if [ "$has_appserver" = 0 ]; then
    deploy_path=$(/root/zulip/scripts/lib/zulip_tools.py make_deploy_path)
    mv /root/zulip "$deploy_path"
    ln -nsf /home/zulip/deployments/next /root/zulip
    ln -nsf "$deploy_path" /home/zulip/deployments/next
    ln -nsf "$deploy_path" /home/zulip/deployments/current
    ln -nsf /etc/zulip/settings.py "$deploy_path"/zproject/prod_settings.py
    mkdir -p "$deploy_path"/prod-static/serve
    cp -rT "$deploy_path"/prod-static/serve /home/zulip/prod-static
    chown -R zulip:zulip /home/zulip /var/log/zulip /etc/zulip/settings.py
fi

if [ -e "/var/run/supervisor.sock" ]; then
    # If supervisor isn't running, no need to chown its socket
    chown zulip:zulip /var/run/supervisor.sock
fi

set +x
cat <<EOF

 Installation complete!

 Now edit /etc/zulip/settings.py and fill in the mandatory values.

 Once you've done that, please run:

 su zulip -c /home/zulip/deployments/current/scripts/setup/initialize-database

 To configure the initial database.
EOF
