#!/bin/sh
#
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#

__cdist_version="1.8.0"

#
# Enable debugging:
#
# __cdist_debug unset -> no debug
# __cdist_debug = 1 -> debug via __cdist_echo
# __cdist_debug = 2 -> debug via set -x
#

: ${__cdist_debug:=0}
[ "$__cdist_debug" = 2 ] && set -x

# Fail if something bogus is going on
set -u

################################################################################
# cconf standard vars prefixed with cdist

__cdist_pwd="$(pwd -P)"
__cdist_mydir="${0%/*}";
__cdist_abs_mydir="$(cd "$__cdist_mydir" && pwd -P)"
__cdist_myname=${0##*/};
__cdist_abs_myname="$__cdist_abs_mydir/$__cdist_myname"

################################################################################
# Names / Constants
#
# Most values can be overriden from outside, so you can
# customise paths as you like (for distributors, geeks and hackers)
#

: ${__cdist_name_bin:=bin}
: ${__cdist_name_cache:=cache}
: ${__cdist_name_code:=code}
: ${__cdist_name_conf_dir:=conf}
: ${__cdist_name_core_dir:=core}
: ${__cdist_name_dot_cdist:=.cdist}
: ${__cdist_name_explorer:=explorer}
: ${__cdist_name_gencode:=gencode}
: ${__cdist_name_gencode_local:=local}
: ${__cdist_name_gencode_remote:=remote}
: ${__cdist_name_global:=global}
: ${__cdist_name_host:=host}
: ${__cdist_name_init:=init}
: ${__cdist_name_manifest:=manifest}
: ${__cdist_name_object:=object}
: ${__cdist_name_object_finished:=done}
: ${__cdist_name_object_prepared:=prepared}
: ${__cdist_name_object_id:=object_id}
: ${__cdist_name_object_source:=source}
: ${__cdist_name_objects_created:=.objects_created}
: ${__cdist_name_out_dir:=out}
: ${__cdist_name_parameter:=parameter}
: ${__cdist_name_parameter_required:=required}
: ${__cdist_name_parameter_optional:=optional}
: ${__cdist_name_require:=require}
: ${__cdist_name_self:=self}
: ${__cdist_name_singleton:=singleton}
: ${__cdist_name_target_host:=target_host}
: ${__cdist_name_target_user:=target_user}
: ${__cdist_name_type:=type}
: ${__cdist_name_type_bin:=type_bin}
: ${__cdist_name_type_explorer:=type_explorer}
: ${__cdist_name_type_explorer_pushed:=.explorer_pushed}

# Used for IDs: Allow everything not starting with - and .
: ${__cdist_sane_regexp:=[^-\.].*}

# Default remote user
: ${__cdist_remote_user:=root}


################################################################################
# Exported variable names (usable for non core)
#
: ${__cdist_name_var_explorer:=__$__cdist_name_explorer}
: ${__cdist_name_var_type_explorer:=__$__cdist_name_type_explorer}
: ${__cdist_name_var_global:=__$__cdist_name_global}
: ${__cdist_name_var_manifest:=__$__cdist_name_manifest}
: ${__cdist_name_var_target_host:=__$__cdist_name_target_host}
: ${__cdist_name_var_target_user:=__$__cdist_name_target_user}
: ${__cdist_name_var_object:=__$__cdist_name_object}
: ${__cdist_name_var_object_id:=__$__cdist_name_object_id}
: ${__cdist_name_var_self:=__$__cdist_name_self}
: ${__cdist_name_var_type:=__$__cdist_name_type}


################################################################################
# Tempfiles
# 
: ${__cdist_tmp_base_dir=/tmp}
__cdist_tmp_dir=$(mktemp -d "$__cdist_tmp_base_dir/cdist.XXXXXXXXXXXX")
__cdist_tmp_file=$(mktemp "$__cdist_tmp_dir/cdist.XXXXXXXXXXXX")

################################################################################
# Local Base
# 
: ${__cdist_local_base_dir:=$__cdist_tmp_dir}

# Cache may *NOT* be below __cdist_local_base_dir!
: ${__cdist_local_base_cache_dir:=$__cdist_abs_mydir/../$__cdist_name_cache}

: ${__cdist_conf_dir:="$(cd "$__cdist_abs_mydir/../conf" && pwd -P)"}
: ${__cdist_core_dir:="$(cd "$__cdist_abs_mydir/../$__cdist_name_core_dir" && pwd -P)"}

: ${__cdist_explorer_dir:=$__cdist_conf_dir/$__cdist_name_explorer}
: ${__cdist_manifest_dir:=$__cdist_conf_dir/$__cdist_name_manifest}
: ${__cdist_manifest_init:=$__cdist_manifest_dir/$__cdist_name_init}
: ${__cdist_type_dir:=$__cdist_conf_dir/$__cdist_name_type}

################################################################################
# Local output
# 
: ${__cdist_out_dir:=$__cdist_local_base_dir/$__cdist_name_out_dir}
: ${__cdist_out_explorer_dir:=$__cdist_out_dir/$__cdist_name_explorer}
: ${__cdist_out_object_dir:=$__cdist_out_dir/$__cdist_name_object}
: ${__cdist_out_type_dir:=$__cdist_out_dir/$__cdist_name_type}
: ${__cdist_out_type_bin_dir:=$__cdist_out_dir/$__cdist_name_type_bin}

: ${__cdist_objects_created:=$__cdist_out_object_dir/$__cdist_name_objects_created}

################################################################################
# Remote base
# 
: ${__cdist_remote_base_dir:=/var/lib/cdist}
: ${__cdist_remote_bin_dir:=$__cdist_remote_base_dir/$__cdist_name_bin}
: ${__cdist_remote_conf_dir:=$__cdist_remote_base_dir/$__cdist_name_conf_dir}
: ${__cdist_remote_core_dir:=$__cdist_remote_base_dir/$__cdist_name_core_dir}

: ${__cdist_remote_explorer_dir:=$__cdist_remote_conf_dir/$__cdist_name_explorer}
: ${__cdist_remote_type_dir:=$__cdist_remote_conf_dir/$__cdist_name_type}

################################################################################
# Remote output
#
: ${__cdist_remote_out_dir:=$__cdist_remote_base_dir/$__cdist_name_out_dir}
: ${__cdist_remote_out_explorer_dir:=$__cdist_remote_out_dir/$__cdist_name_explorer}
: ${__cdist_remote_out_object_dir:=$__cdist_remote_out_dir/$__cdist_name_object}


################################################################################
# Internal functions
#

# *NEW* Load functions from library
for __cdist_lib in $__cdist_core_dir/*; do
   # echo Loading $__cdist_lib ...
   . "$__cdist_lib"
done


################################################################################
# Cache
#
__cdist_cache_dir()
{
   cd "${__cdist_local_base_cache_dir}" && pwd -P
}

__cdist_host_cache_dir()
{
   echo "$(__cdist_cache_dir)/$1" 
}

################################################################################
# Object
#

__cdist_object_code()
{
   echo "$(__cdist_object_dir "$1")/${__cdist_name_code}-$2"
}

__cdist_object_prepared()
{
   echo "$(__cdist_object_dir "$1")/${__cdist_name_object_prepared}"
}

__cdist_object_finished()
{
   echo "$(__cdist_object_dir "$1")/${__cdist_name_object_finished}"
}

__cdist_object_dir()
{
   echo "$(__cdist_object_base_dir "$1")/${__cdist_name_dot_cdist}"
}

__cdist_object_base_dir()
{
   echo "${__cdist_out_object_dir}/$1"
}

__cdist_object_id_from_object()
{
   echo "${1#*/}"
}

__cdist_object_parameter_dir()
{
   echo "$(__cdist_object_dir "$1")/${__cdist_name_parameter}"
}

__cdist_object_require()
{
   echo "$(__cdist_object_dir "$1")/${__cdist_name_require}"
}

__cdist_object_source_name()
{
   echo "$1/${__cdist_name_object_source}"
}

__cdist_object_source()
{
   cat "$(__cdist_object_source_name "$1")"
}

__cdist_object_source_add()
{
   echo "$__cdist_manifest" >> "$(__cdist_object_source_name "$1")"
}

__cdist_object_type_explorer_dir()
{
   echo "$(__cdist_object_dir "$1")/${__cdist_name_explorer}"
}

################################################################################
# Remote
#

__cdist_remote_object_base_dir()
{
   echo "${__cdist_remote_out_object_dir}/$1"
}

__cdist_remote_object_dir()
{
   echo "$(__cdist_remote_object_base_dir "$1")/${__cdist_name_dot_cdist}"
}

__cdist_remote_object_code()
{
   # FIXME: this should probably be __cdist_name_CODE_remote instead, although
   # they have the same name always
   echo "$(__cdist_remote_object_dir "$1")/${__cdist_name_code}-${__cdist_name_gencode_remote}"
}

__cdist_remote_object_parameter_dir()
{
   echo "$(__cdist_remote_object_dir "$1")/${__cdist_name_parameter}"
}

__cdist_remote_object_type_explorer_dir()
{
   echo "$(__cdist_remote_object_dir "$1")/${__cdist_name_explorer}"
}


__cdist_remote_type_explorer_dir()
{
   echo "${__cdist_remote_type_dir}/$1/${__cdist_name_explorer}"
}


################################################################################
# Traps
#

# Remove tempfiles at normal exit
trap __cdist_tmp_removal EXIT


################################################################################
# Type
#
__cdist_type_dir()
{
   echo "${__cdist_type_dir}/$1"
}

__cdist_type_explorer_dir()
{
   echo "${__cdist_type_dir}/$1/${__cdist_name_explorer}"
}

__cdist_type_from_object()
{
   echo "${1%%/*}"
}

__cdist_type_explorer_pushed()
{
   [ -f "${__cdist_out_type_dir}/${__cdist_name_type_explorer_pushed}" ] \
      && grep -q "$1" "${__cdist_out_type_dir}/${__cdist_name_type_explorer_pushed}"
}

__cdist_type_explorer_pushed_add()
{
   [ -d "$__cdist_out_type_dir" ] || mkdir "$__cdist_out_type_dir"
   echo "$1" >> "${__cdist_out_type_dir}/${__cdist_name_type_explorer_pushed}"
}

__cdist_type_gencode()
{
   echo "${__cdist_type_dir}/$1/${__cdist_name_gencode}-$2"
}

__cdist_type_manifest()
{
   echo "${__cdist_type_dir}/$1/${__cdist_name_manifest}"
}

__cdist_type_parameter_dir()
{
   echo "$(__cdist_type_dir "$1")/${__cdist_name_parameter}"
}

__cdist_type_parameter_optional()
{
   echo "$(__cdist_type_parameter_dir "$1")/$__cdist_name_parameter_optional"
}

__cdist_type_parameter_required()
{
   echo "$(__cdist_type_parameter_dir "$1")/$__cdist_name_parameter_required"
}

__cdist_type_singleton()
{
   echo "${__cdist_type_dir}/$1/${__cdist_name_singleton}"
}