#!/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=$(set +o | grep xtrace)
set +o xtrace


# Defaults
# --------

# Set up default directories
GITDIR["django_openstack_auth"]=$DEST/django_openstack_auth

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}

# Tell Tempest this project is present
TEMPEST_SERVICES+=,horizon


# 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 $local_settings
        echo -e "\n$option=$value" >> $file
    elif grep -q "^$section" $file; then
        local 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 {
    local horizon_conf=$(apache_site_config_for horizon)
    sudo rm -f $horizon_conf
}

# 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; ./run_tests.sh -N --compilemessages)
}

# init_horizon() - Initialize databases, etc.
function init_horizon {
    # ``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

    _horizon_config_set $local_settings "" COMPRESS_OFFLINE True

    _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"
    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v2.0\""

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

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

    local horizon_conf=$(apache_site_config_for horizon)

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

    if is_ubuntu; then
        disable_apache_site 000-default
        sudo touch $horizon_conf
    elif is_fedora; then
        sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
    elif is_suse; then
        : # nothing to do
    else
        exit_distro_not_supported "horizon apache configuration"
    fi
    enable_apache_site 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

    DJANGO_SETTINGS_MODULE=openstack_dashboard.settings $django_admin collectstatic --noinput
    DJANGO_SETTINGS_MODULE=openstack_dashboard.settings $django_admin compress --force

}

# install_django_openstack_auth() - Collect source and prepare
function install_django_openstack_auth {
    if use_library_from_git "django_openstack_auth"; then
        local dir=${GITDIR["django_openstack_auth"]}
        git_clone_by_name "django_openstack_auth"
        # Compile message catalogs before installation
        _prepare_message_catalog_compilation
        (cd $dir; python setup.py compile_catalog)
        setup_dev_lib "django_openstack_auth"
    fi
    # if we aren't using this library from git, then we just let it
    # get dragged in by the horizon setup.
}

# 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, including screen
function start_horizon {
    restart_apache_server
    tail_log horizon /var/log/$APACHE_NAME/horizon_error.log
}

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

# NOTE: It can be moved to common functions, but it is only used by compilation
# of django_openstack_auth catalogs at the moment.
function _prepare_message_catalog_compilation {
    local babel_package=$(grep ^Babel $REQUIREMENTS_DIR/global-requirements.txt)
    pip_install "$babel_package"
}


# Restore xtrace
$XTRACE

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