#!/usr/bin/env bash
# ======================================================================
#
# IML DEPLOYMENT ... REPLACE SCRIPT FOR TEMPLATES 
#
# ----------------------------------------------------------------------
#
# ----------------------------------------------------------------------
# 2020-12-15  v0.0  <axel.hahn@iml.unibe.ch>
# 2021-05-07  v1.0  <axel.hahn@iml.unibe.ch>  multiple replacement files
# 2021-05-27  v1.1  <axel.hahn@iml.unibe.ch>  Warn on missing replacements; handle Ruby vars with single and double quotes
# 2021-11-01  v1.2  <axel.hahn@iml.unibe.ch>  save config diffs for deploy_app.sh
# ======================================================================

# ----------------------------------------------------------------------
# CONFIG
# ----------------------------------------------------------------------

tplfile=$1
outfile=$2
shift 2
replacefile=$*
test -z "$replacefile" && replacefile="replace*.txt"

tmpfile=/tmp/myreplacement.tmp
usage="USAGE: $( basename $0 ) TEMPLATE-FILE OUTFILE [optional: REPLACE-DATA-FILE(S)]"

# cfgdiff is set in setProfile in ../deploy_app.sh while running through a profile
# if create_config.sh is used standalone we hide the output
test -z "${cfgdiff}" && cfgdiff=/dev/null

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

# show colored text + line break
function _colmessage(){
    echo -e "\033${1}${2}\033[0m"
}

# show red error message
function _err(){
    _colmessage "[31m" "$1"
}
# show green message
function _ok(){
    _colmessage "[32m" "$1"
}
# show green message
function _warn(){
    _colmessage "[33m" "$1"
}

# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

echo
echo "===== IML DEPLOYMENT :: replace variables in erb syntax ====="
echo

echo "template    : $tplfile"
echo "output      : $outfile"
echo "replacements: $replacefile"
echo

# --- parameter checks
if [ -z "$tplfile" -o -z "$outfile" ]; then
    _err "ERROR: missing params."
    echo $usage
    exit 1
fi

if [ ! -f "$tplfile" ]; then
    _err "ERROR: template [$tplfile] does not exist."
    echo $usage
    exit 2
fi

ls $replacefile >/dev/null
if [ $? -ne 0 ]; then
    _err "ERROR: replacement data file [$replacefile] does not exist."
    echo $usage
    exit 2
fi

typeset -i iReplacements=$( grep "^[a-zA-Z]" $replacefile | grep "=" | wc -l )
echo --- Replacements to apply: $iReplacements
if [ $iReplacements -eq 0 ]; then
    _err "ERROR: No replacements were found ... maybe a wrong syntax?"
    _err "       Use KEY=VALUE; no spaces in front; now quotes around VALUE"
    exit 2
fi

# --- create temporary file to make all replacements in it
cat $tplfile > $tmpfile

# --- apply replace rules
grep "^[a-zA-Z]" $replacefile | grep "=" | while read line
do
    key=$( echo $line | cut -f 1 -d "=" )
    echo $key | grep ":" >/dev/null && key=$( echo $key | rev | cut -f 1 -d ":" | rev )
    val=$( echo $line | cut -f 2- -d "=" )

    # Ruby erb template syntax to write a variable: <% @replace["mykey"] %>
    # Here are 2 regex to handle single and double quotes
    regex1="<\%\=\ *\@replace\['$key'\]\ *\%>"
    regex2="<\%\=\ *\@replace\[\"$key\"\]\ *\%>"

    # Show a warning if both regex do not match
    grep "$regex1" $tmpfile >/dev/null \
      || grep "$regex2" $tmpfile >/dev/null \
      || echo "WARNING: template [$tplfile] has no placeholder key [$key]"

    sed -i "s#$regex1#$val#g" $tmpfile
    sed -i "s#$regex2#$val#g" $tmpfile
done

# --- verify changes
echo
echo --- Changes:
diff "$tplfile" "$tmpfile"
if [ $? -eq 0 ]; then
    _warn "WARNING:"
    _warn "The template was unchanged and will be written directly as output file without any changes."
    # echo Content of relacement files:
    # cat $replacefile
    # exit 3
fi

echo
echo --- Output file:
bHasChanges=0
if [ ! -f "${outfile}" ]; then
    echo "${outfile} File did not exist before - creating it as a new file.">> ${cfgdiff}
    bHasChanges=1
fi

diff "${outfile}" "${tmpfile}"  >/dev/null 2>/dev/null || bHasChanges=1
diff "${outfile}" "${tmpfile}" | sed "s#^#${outfile} #g" >> ${cfgdiff} 2>/dev/null
if [ $bHasChanges -eq 0 ]; then
    _warn "INFO: no changes in ${outfile}."
else
    echo "INFO: writing ${outfile} ..."
    mv -f "${tmpfile}" "${outfile}" || exit 4
fi


ls -l  "${outfile}" 
if [ $? -ne 0 ]; then
    _err "ERROR: unable to write target file $outfile."
    exit 4
fi

echo
echo --- Check missing replacements
grep '<\%\=\ *\@replace\[' ${outfile} >/dev/null
if [ $? -eq 0 ]; then
    echo
    _warn "WARNING: Maybe you need to verify replacements (hmmm, could be a false positive too)"
    grep '<\%\=\ *\@replace\[' ${outfile}
else
    _ok "OK" 
fi

exit 0


# ----------------------------------------------------------------------