#!/usr/local/bin/bash
#
# Copyright (c) 2008, Christopher Cowart and contributors
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions 
# are met:
# * Redistributions of source code must retain the above copyright 
#   notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright 
#   notice, this list of conditions and the following disclaimer in the 
#   documentation and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# $Id: confexport.in 592 2011-12-27 03:04:43Z blee $
#
# This script prepares an "export" of the confman repository for system
# processes to be able to pull. It is intended to be prepared regularly
# by an automated process like cron.

if [ -r /usr/local/share/confman/confmancommon.sh ] ; then
    . /usr/local/share/confman/confmancommon.sh
else
    echo "Can't find confmancommon.sh. Exiting." >&2
    exit 17
fi

# This changes the behavior of some library functions (e.g. URIs, locks)
CONF_EXPORT=true

function print_help {
    echo "usage: $0 [-f] [-d]" >&4
    echo "Type '$0 -h' to display this help and exit." >&4
    conf_cleanExit ${1:-0}
}

FORCE=false
DEBUG=false

while getopts "fdh" OPT 2>&4 ; do
    case "$OPT" in
        f)  FORCE=true ;;
        d)  DEBUG=true ;;
        h)  print_help 0;;
        *)  print_help 1;;
    esac
done

# If we're in debug mode, we should log stderr messages to the logger
# as well. Otherwise, we send them to the bit bucket.
if $DEBUG ; then
    exec 1>&2
else
    exec 1>/dev/null
fi

echo "Export operation started" | conf_logger

confexport_lock_system

umask 077

case ${CONF_EXPORT_STYLE} in
    repository)
        temp_conf_export=$(conf_tmp_file)
        ;;
    module|recipe)
        temp_conf_export=$(conf_tmp_dir)
        ;;
    *)
        echo "Unsupported export style: ${CONF_EXPORT_STYLE}" >&2
        exit 1
        ;;
esac

if [ -z "${temp_conf_export}" ] ; then
    echo "Could not create tempfile. Exiting." >&2
    exit 1
fi

if [ -z "${CONF_EXPORT_WORK_PATH}" ]; then
    WORK_PATH=$(conf_tmp_dir)
    conf_debug "Using temporary export working copy at ${WORK_PATH}"
else
    WORK_PATH="${CONF_EXPORT_WORK_PATH}"
    conf_debug "Using persistent export working copy at ${WORK_PATH}"
fi

conf_checkout_tree

repo_export="${CONF_EXPORT_STYLE}:$(conf_revision_svn)"
sys_export="$(conf_export_sysrev)"

conf_debug "repo_export: ${repo_export}"
conf_debug "sys_export: ${sys_export}"

if [ "${sys_export}" = "${repo_export}" ]; then
    if ! ${FORCE}; then
        echo "System is up to date." | conf_logger
        conf_cleanExit 0
    fi
fi

repo_method=$(echo ${repo_export} | cut -d ':' -f 1)
sys_method=$(echo ${sys_export} | cut -d ':' -f 1)
repo_revision=$(echo ${repo_export} | cut -d ':' -f 2)
sys_revision=$(echo ${sys_export} | cut -d ':' -f 2)

if [ "${sys_method}" != "${repo_method}" ]; then
    echo "Export style change detected: ${sys_method} -> ${repo_method}"
    if ${CONF_EXPORT_INCREMENTAL}; then
        echo "Ignoring CONF_EXPORT_INCREMENTAL during export style change"
        CONF_EXPORT_INCREMENTAL="false"
    fi
fi

if [ "${sys_revision}" -gt "${repo_revision}" ]; then
    echo "Error: The last export was newer than the current repository.  Exiting without making changes." >&2
    conf_cleanExit 1
fi

if ! conf_export "${temp_conf_export}" "${sys_revision}" "${repo_revision}"; then
    echo "Error: The export failed. Exiting." >&2
    rm -rf "${temp_conf_export}"
    conf_cleanExit 1
fi

# Prepare the new export
chown -R ${CONF_EXPORT_USER}:${CONF_EXPORT_GROUP} "${temp_conf_export}" || exit 1
chmod -R ${CONF_EXPORT_MODE} "${temp_conf_export}" || exit 1

# Switch to the new export
old_conf_export=$(conf_tmp_dir)
if [ -e "${CONF_EXPORT_FILE}" ]; then
    mv "${CONF_EXPORT_FILE}" "${old_conf_export}" || exit 1
fi
mv "${temp_conf_export}" "${CONF_EXPORT_FILE}"

conf_record_export

echo "Export operation finished successfully" | conf_logger

confexport_unlock_system

# Remove the old export
rm -rf "${old_conf_export}"

# If CONF_EXPORT_WORK_PATH is not set, we were using a temporary
# directory, so clean it up
if [ -z "${CONF_EXPORT_WORK_PATH}" ]; then
    rm -rf "${WORK_PATH}"
fi

conf_cleanExit 0
