#!/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

    # 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)

    # 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;
    \" $FILES/apache-horizon.template >$horizon_conf"

    if is_ubuntu; then
        disable_apache_site 000-default
        sudo touch $horizon_conf
    elif is_fedora || is_suse; 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

    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:
