#!/bin/sh

VERSION="0.0.1"
RELEASE=""

set -u
# set -x

hosts=
cache_dir=~/.cdist/cache

do_all=1
do_global_explorer=
do_type_explorer=
do_script_stdout=
do_script_stderr=
do_gencode=
do_code=
do_messages=
do_parameter=
delimiter=':'
ln=
filename_prefix=1
verbose=0

myname=${0##*/}

print_version()
{
    printf "%s %s %s\n" "${myname}" "${VERSION}" "${RELEASE}"
}

usage()
{
    cat << eof
${myname}: [options] [host...]
eof

    print_version

    cat << eof

Dump data from cache directories.

host      
    Dump data for specified hosts. If not specified then all data
    from cache directory is dumped.

Options
 -a             dump all
 -C CACHE-DIR   use specified CACHE-DIR (default: ~/.cdist/cache)
 -c             dump code-*
 -d DELIMITER   delimiter used for filename and line number prefix (default: ':')
 -E             dump global explorers
 -e             dump type explorers
 -F             disable filename prefix (enabled by default)
 -f             enable filename prefix (default)
 -g             dump gencode-*
 -h             show this help screen and exit
 -L             disable line number prefix (default)
 -l             enable line number prefix (disabled by default)
 -m             dump messages
 -o             dump executions' stdout
 -p             dump parameters
 -r             dump executions' stderr
 -V             show version and exit
 -v             increase verbosity
eof
}

exit_err()
{
    printf "%s\n" "$1"
    exit 1
}

# parse options
while [ "$#" -ge 1 ]
do
    case "$1" in
        -a)
            do_all=1
            ;;
        -C)
            if [ "$#" -ge 2 ]
            then
                case "$2" in
                    -*)
                        exit_err "Missing cache directory"
                        ;;
                    *)
                        cache_dir="$2"
                        shift
                        ;;
                esac
            else
                exit_err "Missing cache directory"
            fi
            ;;
        -c)
            do_code=1
            do_all=
            ;;
        -d)
            if [ "$#" -ge 2 ]
            then
                case "$2" in
                    -*)
                        exit_err "Missing delimiter"
                        ;;
                    *)
                        delimiter="$2"
                        shift
                        ;;
                esac
            else
                exit_err "Missing delimiter"
            fi
            ;;
        -E)
            do_global_explorer=1
            do_all=
            ;;
        -e)
            do_type_explorer=1
            do_all=
            ;;
        -F)
            filename_prefix=
            ;;
        -f)
            filename_prefix=1
            ;;
        -g)
            do_gencode=1
            do_all=
            ;;
        -h)
            usage
            exit 0
            ;;
        -L)
            ln=
            ;;
        -l)
            ln=1
            ;;
        -m)
            do_messages=1
            do_all=
            ;;
        -o)
            do_script_stdout=1
            do_all=
            ;;
        -p)
            do_parameter=1
            do_all=
            ;;
        -r)
            do_script_stderr=1
            do_all=
            ;;
        -V)
            print_version
            exit 0
            ;;
        -v)
            verbose=$((verbose + 1))
            ;;
        *)
            hosts="${hosts} $1"
            break
            ;;
    esac
    shift
done

if [ "${ln}" = "1" ]
then
    ln="NR \"${delimiter}\""
fi

if [ "${filename_prefix}" = "1" ]
then
    filename_prefix="{}${delimiter}"
fi

if [ "${do_all}" = "1" ]
then
    do_global_explorer=1
    do_type_explorer=1
    do_script_stdout=1
    do_script_stderr=1
    do_gencode=1
    do_code=1
    do_messages=1
    do_parameter=1
fi

set -- -size +0
set -- "$@" \(
or=

print_verbose()
{
    if [ "${verbose}" -ge "$1" ]
    then
        printf "%s\n" "$2"
    fi
}

hor_line()
{
    if [ $# -gt 0 ]
    then
        c="$1"
    else
        c='='
    fi
    printf "%78s\n" "" | tr ' ' "${c}"
}

if [ "${do_global_explorer}" ]
then
    print_verbose 2 "Dumping global explorers"
    # shellcheck disable=SC2086
    set -- "$@" ${or} \( \
                -path "*/explorer/*" -a \
                ! -path "*/conf/*" -a \
                ! -path "*/object/*/explorer/*" \
            \)
    or="-o"
fi

if [ "${do_type_explorer}" ]
then
    print_verbose 2 "Dumping type explorers"
    set -- "$@" ${or} -path "*/object/*/explorer/*"
    or="-o"
fi

if [ "${do_script_stdout}" ]
then
    print_verbose 2 "Dumping execution's stdout"
    set -- "$@" ${or} -path "*/stdout/*"
    or="-o"
fi

if [ "${do_script_stderr}" ]
then
    print_verbose 2 "Dumping execution's stderr"
    set -- "$@" ${or} -path "*/stderr/*"
    or="-o"
fi

if [ "${do_gencode}" ]
then
    print_verbose 2 "Dumping gencode-*"
    set -- "$@" ${or} \( -name "gencode-*" -a ! -path "*/stdout/*" -a ! -path "*/stderr/*" \)
    or="-o"
fi

if [ "${do_code}" ]
then
    print_verbose 2 "Dumping code-*"
    set -- "$@" ${or} \( -name "code-*" -a ! -path "*/stdout/*" -a ! -path "*/stderr/*" \)
    or="-o"
fi

if [ "${do_messages}" ]
then
    print_verbose 2 "Dumping messages"
    set -- "$@" ${or} -name "messages"
    or="-o"
fi

if [ "${do_parameter}" ]
then
    print_verbose 2 "Dumping parameters"
    set -- "$@" ${or} -path "*/parameter/*"
    or="-o"
fi

set -- "$@" \)
set -- '.' "$@" -exec awk -v prefix="${filename_prefix}" "{print prefix ${ln} \$0}" {} \;

# printf "+ %s\n" "$*"

print_verbose 2 "Using cache dir: ${cache_dir}"

OLD_PWD=$(pwd)
cd "${cache_dir}" || exit

# If no host is specified then search all.
[ -z "${hosts}" ] && hosts="-"

for host in ${hosts}
do
    [ "${host}" = "-" ] && host=
    # find host cache directory
    host_dir=$(find . -name target_host -exec grep -l "${host}" {} +)
    print_verbose 3 "found host directory files:"
    print_verbose 3 "${host_dir}"

    OLD_IFS="${IFS}"
    IFS="
    "

    for d in ${host_dir}
    do
        dir=$(dirname "${d}")

        print_verbose 0 "target host: $(cat "${dir}/target_host"), host directory: ${dir}"
        hor_line '='

        PREV_PWD=$(pwd)
        cd "${dir}" || exit
        # set -x
        find "$@"
        # set +x
        cd "${PREV_PWD}" || exit
    done
    IFS="${OLD_IFS}"
done
cd "${OLD_PWD}" || exit