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

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

# 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
        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
    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 "" WEBROOT \"$HORIZON_APACHE_ROOT/\"
    _horizon_config_set $local_settings "" CUSTOM_THEME_PATH \"themes/webroot\"

    _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_API_VERSIONS {\"identity\":3}
    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v3\""

    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
    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;
        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; 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 {
    pip_install_gr Babel
}


# Restore xtrace
$_XTRACE_HORIZON

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