# lib/apache
# Functions to control configuration and operation of apache web server

# Dependencies:
#
# - ``functions`` file
# -``STACK_USER`` must be defined

# lib/apache exports the following functions:
#
# - is_apache_enabled_service
# - install_apache_wsgi
# - config_apache_wsgi
# - enable_apache_site
# - disable_apache_site
# - start_apache_server
# - stop_apache_server
# - restart_apache_server

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

# Allow overriding the default Apache user and group, default to
# current user and his default group.
APACHE_USER=${APACHE_USER:-$STACK_USER}
APACHE_GROUP=${APACHE_GROUP:-$(id -gn $APACHE_USER)}


# Set up apache name and configuration directory
if is_ubuntu; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=sites-available
elif is_fedora; then
    APACHE_NAME=httpd
    APACHE_CONF_DIR=conf.d
elif is_suse; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=vhosts.d
fi

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

# is_apache_enabled_service() checks if the service(s) specified as arguments are
# apache enabled by the user in ``APACHE_ENABLED_SERVICES`` as web front end.
#
# Multiple services specified as arguments are ``OR``'ed together; the test
# is a short-circuit boolean, i.e it returns on the first match.
#
# Uses global ``APACHE_ENABLED_SERVICES``
# APACHE_ENABLED_SERVICES service [service ...]
function is_apache_enabled_service() {
    services=$@
    for service in ${services}; do
        [[ ,${APACHE_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
    done
    return 1
}

# install_apache_wsgi() - Install Apache server and wsgi module
function install_apache_wsgi() {
    # Apache installation, because we mark it NOPRIME
    if is_ubuntu; then
        # Install apache2, which is NOPRIME'd
        install_package apache2 libapache2-mod-wsgi
        # WSGI isn't enabled by default, enable it
        sudo a2enmod wsgi
    elif is_fedora; then
        sudo rm -f /etc/httpd/conf.d/000-*
        install_package httpd mod_wsgi
    elif is_suse; then
        install_package apache2 apache2-mod_wsgi
        # WSGI isn't enabled by default, enable it
        sudo a2enmod wsgi
    else
        exit_distro_not_supported "apache installation"
    fi
}

# enable_apache_site() - Enable a particular apache site
function enable_apache_site() {
    local site=$@
    if is_ubuntu; then
        sudo a2ensite ${site}
    elif is_fedora; then
        # fedora conf.d is only imported if it ends with .conf so this is approx the same
        sudo mv /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site} /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf
    fi
}

# disable_apache_site() - Disable a particular apache site
function disable_apache_site() {
    local site=$@
    if is_ubuntu; then
        sudo a2dissite ${site}
    elif is_fedora; then
        sudo mv /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}
    fi
}

# start_apache_server() - Start running apache server
function start_apache_server() {
    start_service $APACHE_NAME
}

# stop_apache_server() - Stop running apache server
function stop_apache_server() {
    if [ -n "$APACHE_NAME" ]; then
        stop_service $APACHE_NAME
    else
        exit_distro_not_supported "apache configuration"
    fi
}

# restart_apache_server
function restart_apache_server() {
    restart_service $APACHE_NAME
}

# Restore xtrace
$XTRACE

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