#!/bin/bash
#
# lib/horizon
# Functions to control the configuration and operation of the horizon service

# Dependencies:
#
# - ``functions`` file
# - ``apache`` file
# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined

# ``stack.sh`` calls the entry points in this order:
#
# - install_horizon
# - configure_horizon
# - init_horizon
# - start_horizon
# - stop_horizon
# - cleanup_horizon

# Save trace setting
_XTRACE_HORIZON=$(set +o | grep xtrace)
set +o xtrace


# Defaults
# --------

HORIZON_DIR=$DEST/horizon

# local_settings.py is used to customize Dashboard settings.
# The example file in Horizon repo is used by default.
HORIZON_SETTINGS=${HORIZON_SETTINGS:-$HORIZON_DIR/openstack_dashboard/local/local_settings.py.example}

# Functions
# ---------

# utility method of setting python option
function _horizon_config_set {
    local file=$1
    local section=$2
    local option=$3
    local value=$4

    if [ -z "$section" ]; then
        sed -e "/^$option/d" -i $file
        echo "$option = $value" >> $file
    elif grep -q "^$section" $file; then
        local line
        line=$(sed -ne "/^$section/,/^}/ { /^ *'$option':/ p; }" $file)
        if [ -n "$line" ]; then
            sed -i -e "/^$section/,/^}/ s/^\( *'$option'\) *:.*$/\1: $value,/" $file
        else
            sed -i -e "/^$section/a\    '$option': $value," $file
        fi
    else
        echo -e "\n\n$section = {\n    '$option': $value,\n}" >> $file
    fi
}



# Entry Points
# ------------

# cleanup_horizon() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_horizon {
    disable_apache_site horizon
    sudo rm -f $(apache_site_config_for horizon)
}

# configure_horizon() - Set config files, create data dirs, etc
function configure_horizon {
    setup_develop $HORIZON_DIR

    # Compile message catalogs.
    # Horizon is installed as develop mode, so we can compile here.
    # Message catalog compilation is handled by Django admin script,
    # so compiling them after the installation avoids Django installation twice.
    (cd $HORIZON_DIR; $PYTHON manage.py compilemessages)

    # ``local_settings.py`` is used to override horizon default settings.
    local local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
    cp $HORIZON_SETTINGS $local_settings

    # Ensure local_setting.py file ends with EOL (newline)
    echo >> $local_settings

    _horizon_config_set $local_settings "" WEBROOT \"$HORIZON_APACHE_ROOT/\"

    _horizon_config_set $local_settings "" COMPRESS_OFFLINE True
    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_DEFAULT_ROLE \"member\"

    _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"

    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_URI}/v3\""

    # note(trebskit): if HOST_IP points at non-localhost ip address, horizon cannot be accessed
    # from outside the virtual machine. This fixes is meant primarily for local development
    # purpose
    _horizon_config_set $local_settings "" ALLOWED_HOSTS [\"*\"]

    if [ -f $SSL_BUNDLE_FILE ]; then
        _horizon_config_set $local_settings "" OPENSTACK_SSL_CACERT \"${SSL_BUNDLE_FILE}\"
    fi

    if is_service_enabled ldap; then
        _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT "True"
    fi

    if is_service_enabled c-bak; then
        _horizon_config_set $local_settings OPENSTACK_CINDER_FEATURES enable_backup "True"
    fi

    # Create an empty directory that apache uses as docroot
    sudo mkdir -p $HORIZON_DIR/.blackhole

    local horizon_conf
    horizon_conf=$(apache_site_config_for horizon)

    local wsgi_venv_config=""
    if [[ "$GLOBAL_VENV" == "True" ]] ; then
        wsgi_venv_config="WSGIPythonHome $DEVSTACK_VENV"
    fi

    # Configure apache to run horizon
    # Set up the django horizon application to serve via apache/wsgi
    sudo sh -c "sed -e \"
        s,%USER%,$APACHE_USER,g;
        s,%GROUP%,$APACHE_GROUP,g;
        s,%HORIZON_DIR%,$HORIZON_DIR,g;
        s,%APACHE_NAME%,$APACHE_NAME,g;
        s,%DEST%,$DEST,g;
        s,%WEBROOT%,$HORIZON_APACHE_ROOT,g;
        s,%WSGIPYTHONHOME%,$wsgi_venv_config,g;
    \" $FILES/apache-horizon.template >$horizon_conf"

    if is_ubuntu; then
        disable_apache_site 000-default
        sudo touch $horizon_conf
    elif is_fedora; then
        : # nothing to do
    else
        exit_distro_not_supported "horizon apache configuration"
    fi
    enable_apache_site horizon
}

# init_horizon() - Initialize databases, etc.
function init_horizon {
    # Remove old log files that could mess with how DevStack detects whether Horizon
    # has been successfully started (see start_horizon() and functions::screen_it())
    # and run_process
    sudo rm -f /var/log/$APACHE_NAME/horizon_*

    # Setup alias for django-admin which could be different depending on distro
    local django_admin
    if type -p django-admin > /dev/null; then
        django_admin=django-admin
    else
        django_admin=django-admin.py
    fi

    # These need to be run after horizon plugins are configured.
    DJANGO_SETTINGS_MODULE=openstack_dashboard.settings $django_admin collectstatic --noinput
    DJANGO_SETTINGS_MODULE=openstack_dashboard.settings $django_admin compress --force

}

# install_horizon() - Collect source and prepare
function install_horizon {
    # Apache installation, because we mark it NOPRIME
    install_apache_wsgi

    # Install the memcache library so that horizon can use memcached as its
    # cache backend
    pip_install_gr pymemcache

    git_clone $HORIZON_REPO $HORIZON_DIR $HORIZON_BRANCH
}

# start_horizon() - Start running processes
function start_horizon {
    restart_apache_server
}

# stop_horizon() - Stop running processes
function stop_horizon {
    stop_apache_server
}

# Restore xtrace
$_XTRACE_HORIZON

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
