# 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:
#
# - install_apache_wsgi
# - config_apache_wsgi
# - apache_site_config_for
# - 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=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/sites-available}
elif is_fedora; then
    APACHE_NAME=httpd
    APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/conf.d}
elif is_suse; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/vhosts.d}
fi

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

# apache_site_config_for() - The filename of the site's configuration file.
# This function uses the global variables APACHE_NAME and APACHE_CONF_DIR.
#
# On Ubuntu 14.04, the site configuration file must have a .conf suffix for a2ensite and a2dissite to
# recognise it. a2ensite and a2dissite ignore the .conf suffix used as parameter. The default sites'
# files are 000-default.conf and default-ssl.conf.
#
# On Ubuntu 12.04, the site configuration file may have any format, as long as it is in
# /etc/apache2/sites-available/. a2ensite and a2dissite need the entire file name to work. The default
# sites' files are default and default-ssl.
#
# On Fedora and openSUSE, any file in /etc/httpd/conf.d/ whose name ends with .conf is enabled.
#
# On RHEL and CentOS, things should hopefully work as in Fedora.
#
# The table below summarizes what should happen on each distribution:
# +----------------------+--------------------+--------------------------+--------------------------+
# | Distribution         | File name          | Site enabling command    | Site disabling command   |
# +----------------------+--------------------+--------------------------+--------------------------+
# | Ubuntu 12.04         | site               | a2ensite site            | a2dissite site           |
# | Ubuntu 14.04         | site.conf          | a2ensite site            | a2dissite site           |
# | Fedora, RHEL, CentOS | site.conf.disabled | mv site.conf{.disabled,} | mv site.conf{,.disabled} |
# +----------------------+--------------------+--------------------------+--------------------------+
function apache_site_config_for {
    local site=$@
    if is_ubuntu; then
        local apache_version=$(sudo /usr/sbin/apache2ctl -v | awk '/Server version/ {print $3}' | cut -f2 -d/)
        if [[ "$apache_version" =~ ^2\.2\. ]]; then
            # Ubuntu 12.04 - Apache 2.2
            echo $APACHE_CONF_DIR/${site}
        else
            # Ubuntu 14.04 - Apache 2.4
            echo $APACHE_CONF_DIR/${site}.conf
        fi
    elif is_fedora || is_suse; then
        # fedora conf.d is only imported if it ends with .conf so this is approx the same
        local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
        if [ -f $enabled_site_file ]; then
            echo ${enabled_site_file}
        else
            echo ${enabled_site_file}.disabled
        fi
    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 || is_suse; then
        local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
        # Do nothing if site already enabled or no site config exists
        if [[ -f ${enabled_site_file}.disabled ]] && [[ ! -f ${enabled_site_file} ]]; then
            sudo mv ${enabled_site_file}.disabled ${enabled_site_file}
        fi
    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 || is_suse; then
        local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
        # Do nothing if no site config exists
        if [[ -f ${enabled_site_file} ]]; then
            sudo mv ${enabled_site_file} ${enabled_site_file}.disabled
        fi
    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 {
    # Apache can be slow to stop, doing an explicit stop, sleep, start helps
    # to mitigate issues where apache will claim a port it's listening on is
    # still in use and fail to start.
    stop_service $APACHE_NAME
    sleep 3
    start_service $APACHE_NAME
}

# Restore xtrace
$XTRACE

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