#!/usr/bin/env bash

# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Install and start Freezer service

# add the following to localrc:
#   enable_service freezer-api
#
# Dependencies:
# - functions
# - OS_AUTH_URL for auth in api
# - DEST set to the destination directory
# - SERVICE_PASSWORD, SERVICE_TENANT_NAME for auth in api
# - STACK_USER service user

# functions called by the plugin.sh script
# source plugin.sh <mode> [phase]
# ---------
# - <stack>
#   - <stack> [pre-install]
#   - <stack> [install]
#     - install_freezer_api
#   - <stack> [post-config]
#     - configure_freezer_api
#     - create_freezer_api_accounts
#   - <stack> [extra]
#     - init_freezer_api
#     - start_freezer_api
# - <unstack>
#   - stop_freezer_api
# - <clean>
#   - cleanup_freezer_api

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


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

function is_freezer_api_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"freezer-api" ]] && return 0
}


# executed during: clean
function cleanup_freezer_api {
    sudo rm -f $(apache_site_config_for freezer-api)
    ${TOP_DIR}/pkg/elasticsearch.sh uninstall
}

# add openjdk-7 repo support for xenial
function add_jdk7_rep {

    sudo add-apt-repository -y ppa:openjdk-r/ppa
    apt_get_update
}

# executed during: stack install
function install_freezer_api {

    if is_ubuntu; then
        add_jdk7_rep
    fi
    git_clone $FREEZER_API_REPO $FREEZER_API_DIR $FREEZER_API_BRANCH

    ${TOP_DIR}/pkg/elasticsearch.sh download
    ${TOP_DIR}/pkg/elasticsearch.sh install

    setup_develop $FREEZER_API_DIR

    if [[ "${FREEZER_API_SERVER_TYPE}" == "uwsgi" ]]; then
        pip_install 'uwsgi'
    fi
}

# Setup python-freezerclient
function install_freezerclient {

    git_clone $FREEZERCLIENT_REPO $FREEZERCLIENT_DIR $FREEZERCLIENT_BRANCH
    setup_develop $FREEZERCLIENT_DIR
}

# executed during: stack post-config
function configure_freezer_api {

    [ ! -d $FREEZER_API_CONF_DIR ] && sudo mkdir -m 755 -p $FREEZER_API_CONF_DIR
    sudo chown $USER $FREEZER_API_CONF_DIR

    [ ! -d $FREEZER_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $FREEZER_API_LOG_DIR
    sudo chown $USER $FREEZER_API_LOG_DIR

    sudo cp $FREEZER_API_DIR/etc/freezer/freezer-api.conf.sample $FREEZER_API_CONF_DIR/freezer-api.conf
    sudo cp $FREEZER_API_DIR/etc/freezer/freezer-paste.ini $FREEZER_API_CONF_DIR/freezer-paste.ini
    sudo cp $FREEZER_API_DIR/etc/freezer/policy.json $FREEZER_API_CONF_DIR/policy.json

    # enable debuging
    iniset $FREEZER_API_CONF 'DEFAULT' debug True

    # set paste configuration
    iniset $FREEZER_API_CONF 'paste_deploy' config_file $FREEZER_API_CONF_DIR/freezer-paste.ini

    # make sure the stack user has the right permissions on the config folder
    sudo chown -R $USER $FREEZER_API_CONF_DIR

    #set elasticsearch configuration
    iniset $FREEZER_API_CONF 'storage' db elasticsearch
    iniset $FREEZER_API_CONF 'storage' index freezer
    iniset $FREEZER_API_CONF 'storage' number_of_replicas 0
    iniset $FREEZER_API_CONF 'storage' hosts http://$SERVICE_HOST:9200

    # set keystone configuration
    iniset $FREEZER_API_CONF 'keystone_authtoken' auth_protocol $KEYSTONE_AUTH_PROTOCOL
    iniset $FREEZER_API_CONF 'keystone_authtoken' auth_host $KEYSTONE_AUTH_HOST
    iniset $FREEZER_API_CONF 'keystone_authtoken' auth_port $KEYSTONE_AUTH_PORT
    iniset $FREEZER_API_CONF 'keystone_authtoken' admin_user freezer
    iniset $FREEZER_API_CONF 'keystone_authtoken' admin_password $SERVICE_PASSWORD
    iniset $FREEZER_API_CONF 'keystone_authtoken' admin_tenant_name $SERVICE_TENANT_NAME
    iniset $FREEZER_API_CONF 'keystone_authtoken' auth_uri $KEYSTONE_AUTH_URI_V3
    iniset $FREEZER_API_CONF 'keystone_authtoken' identity_uri $KEYSTONE_AUTH_URI

    if [[ "${FREEZER_API_SERVER_TYPE}" == "apache2" ]]; then
        echo_summary "Configuring Freezer API wsgi app in Apache"
        configure_apache_freezer_app
    fi

    # TODO certs and more recent options such as elasticsearch connection parameters
}


# executed during: stack extra
function init_freezer_api {
    # this also waits for elasticsearch to start
    ${TOP_DIR}/pkg/elasticsearch.sh start

    # put elasticsearch mappings
    freezer-manage db update
    freezer-manage db show
}


# executed during: stack extra
function start_freezer_api {
    if [[ "${FREEZER_API_SERVER_TYPE}" == "uwsgi" ]]; then
        run_process freezer-api "uwsgi --http :$FREEZER_API_PORT --need-app --master --module freezer_api.cmd.api:application"
        sleep 1
    elif [[ "${FREEZER_API_SERVER_TYPE}" == "apache2" ]]; then
        enable_apache_site freezer-api
        restart_apache_server
        tail_log freezer-api /var/log/$APACHE_NAME/freezer-api.log
        tail_log freezer-access /var/log/$APACHE_NAME/freezer-api_access.log
    fi
}


# executed during: stop
function stop_freezer_api {
    ${TOP_DIR}/pkg/elasticsearch.sh stop
    if [[ "${FREEZER_API_SERVER_TYPE}" == "uwsgi" ]]; then
        killall -9 uwsgi
    fi
    stop_process freezer-api
}


# utility function
function get_id {
    echo `"$@" | awk '/ id / { print $4 }'`
}


# executed during: stack post-config
function create_freezer_api_accounts {
    #
    # Setup admin user
    #
    SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service}
    local admin_role=$(get_or_create_role "admin")

    local freezer_user=$(openstack user create \
                            --password "$SERVICE_PASSWORD" \
                            --project "$SERVICE_TENANT_NAME" \
                            --email "freezer@example.com" \
                            freezer \
                            | grep " id " | get_field 2)

    get_or_add_user_project_role $admin_role $freezer_user $SERVICE_TENANT_NAME

    #
    # freezer backup service registration
    #
    local freezer_service=$(get_or_create_service "freezer" "backup" "Freezer Backup Service")

    #
    # freezer backup endpoint registration
    #
    get_or_create_endpoint "$freezer_service" \
         "$REGION_NAME" \
         "$FREEZER_API_SERVICE_PROTOCOL://$SERVICE_HOST:$FREEZER_API_PORT" \
         "$FREEZER_API_SERVICE_PROTOCOL://$SERVICE_HOST:$FREEZER_API_PORT" \
         "$FREEZER_API_SERVICE_PROTOCOL://$SERVICE_HOST:$FREEZER_API_PORT"
}


function configure_apache_freezer_app {
    local freezer_api_apache_conf=$(apache_site_config_for freezer-api)

    # Add a %LOCAL_LISTEN% parameter to conditionally listen 127.0.0.1 when
    # not already doing so to allow monitoring checks
    local local_listen="Listen 127.0.0.1:$FREEZER_API_PORT"
    if [[ "${SERVICE_HOST}" == "127.0.0.1" ]] || [[ "${SERVICE_HOST}" == "localhost" ]]; then
        local_listen=""
    fi

    sudo cp $FREEZER_API_FILES/apache-freezer-api.template $freezer_api_apache_conf
    sudo sed -e "
        s|%FREEZER_API_PORT%|$FREEZER_API_PORT|g;
        s|%SERVICE_HOST%|$SERVICE_HOST|g;
        s|%USER%|$STACK_USER|g;
        s|%FREEZER_API_DIR%|$FREEZER_API_DIR|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%VIRTUALENV%|$venv_path|g;
        s|%LOCAL_LISTEN%|$local_listen|g
    " -i $freezer_api_apache_conf
}

# Restore xtrace
$XTRACE
