#!/usr/bin/bash
#shellcheck disable=SC1090

. "$(sfpath)" || exit 3

shellfu import pretty

#

usage() {
    mkusage "$@" "[options] SCRIPT" \
        -- \
        "Run SCRIPT, see what it would load and print its 'portable'"     \
        "version, ie. with those modules embedded inside."                \
        -o \
            "-v     enable verbose output"                                \
            "-d     enable debugging output"                              \
        -- \
        "WARNING: sfembed is highly experimental, probably dangerous and" \
        "does not always work (namely, if module loading is dynamic)."    \
        -- \
        "Calling sfembed WILL RUN provided SCRIPT (with no arguments);"   \
        "currently that's how it finds out what the SCRIPT would need."
}

chk_applicable() {
    #
    # Check if script file is properly formed
    #
    # Not all scripts are applicable for embedding.  Check
    # if the file is usable.
    #
    :
    #TODO: for starters, file must only contain shellfu header, imports, main() and nothing else
}

mkbody() {
    debug -v ScriptFullPath
    mkhead      || return $?
    mkmodules   || return $?
    mkpayload   || return $?
    mkfoot      || return $?
}

mkmodules() {
    #
    # Print each module body w/ header
    #
    local modlist=__shellfu_embed__modlist
    local Module
    local ModuleHash
    (
        SHELLFU_EMBEDTMP="$modlist" "$ScriptFullPath" >&2
    )
    #shellcheck disable=SC2030
    awk '!x[$0]++' "$modlist" \
      | while read -r Module;
        do
            ModuleHash=$(md5sum "$Module")
            think "appending: $Module"
            mkmodule "$Module"
        done
}

mkpayload() {
    cat "$ScriptFullPath"
}

mkfoot() {
    echo "#"
    echo "# end of shellfu-embedded shell script"
    echo "#"
}

#shellcheck disable=SC2031
mkmodule() {
    #
    # Print single module body
    #
    echo "#"
    echo "# begin module: $ModuleHash"
    echo "#"
    echo
    cat "$Module"
    echo
    echo "#"
    echo "# end module: $ModuleHash"
    echo "#"
    echo
}

mkhead() {
    #
    # Print header of the final script
    #
    echo "#!/bin/bash"
    echo "#"
    echo "# shellfu embedded: $ScriptFullPath"
    echo "# shellfu version: $SHELLFU_VERSION"
    echo "#"
    echo
    echo "# neuter any shellfu and sfpath calls"
    echo "shellfu() { :; }"
    echo "sfpath() { echo /dev/null; }"
    #FIXME: assumes that shellfu and sfpath are not installed
    #       I.e. beats the use case when embedding is done to
    #       avoid conflict.
    echo
}

do_embed() {
    local tmp               # temporary dir to run in
    local es=0              # exit status of this function
    local ScriptFullPath    # full path to script to embed in
    tmp=$(mktemp -d -t shellfu_embed.XXXXXXXX)
    ScriptFullPath=$(readlink -f "$Script")
    pushd "$tmp" >/dev/null
        mkbody; es=$?
    popd >/dev/null
    rm -r "$tmp"
    return $es
}

main() {
    local Script        # script to embed libraries into
    #shellcheck disable=SC2034
    while true; do case "$1" in
        -d) PRETTY_DEBUG=true; shift ;;
        -v) PRETTY_VERBOSE=true; shift ;;
        -*) usage -w "unknown argument: $1" ;;
        *)  break ;;
    esac done
    Script="$1"
    test -n "$Script" || usage -w "no SCRIPT?"
    test -f "$Script" || die "no such file: $Script"
    test -r "$Script" || die "cannot read: $Script"
    chk_applicable "$Script" || die "not applicable for embedding: $Script"
    debug -v Script
    do_embed
}

main "$@"
