#!/bin/bash
###############################################################################
#
# Genapp tool
#
# Copyright (c) 2026 Michel Mehl. All rights reserved.
#
# ------------------------------------------------------------------------------
#
# This file implements the Genapp tool to generate shell script app skeletons
# using the shell-api library. 
#
# It includes a sub-skeleton file for managing options, as well as one including
# help functions to enable packaging with dpkg.
#
# ------------------------------------------------------------------------------
#
# Report bugs to michel.mehl@slashetc.fr
#
###############################################################################

# GENAPP__VARS is aimed at storing variables specific to this app
# to avoid conflicts with other vars should this file be included elsewhere
declare -A GENAPP__VARS

Genapp__sourcedirname="${BASH_SOURCE[0]%/*}" # "$(dirname ${BASH_SOURCE[0]})"
GENAPP__VARS["MYDIR"]="$(readlink -f "${Genapp__sourcedirname}")"

if [[ ! -v __SHELL_API_CORE_LOADED__ ]]; then
    source "${GENAPP__VARS["MYDIR"]}/shell-api-core.sh" "Genapp"
fi

:<<'EOF'
# If necessary include of these modules
eval $_loadm<<<'shell-api-sys'          # process control functions
eval $_loadm<<<'shell-api-dev'          # device access functions
eval $_loadm<<<'shell-api-packing'      # package management functions (loading)
eval $_loadm<<<'shell-api-net'          # network related functions
EOF

eval $_loadm<<<'shell-api-yaml'         # YAML read/write functions, mandatory core has a dependency on it

source "${GENAPP__VARS["MYDIR"]}/genapp__vars.sh" 
source "${GENAPP__VARS["MYDIR"]}/genapp__options.sh" 
source "${GENAPP__VARS["MYDIR"]}/genapp__help.sh" 

Genapp__parseArgsHandleOptionLessArg() {
        local rank=$1
        shift
        local value="$@"

        # Handle here optionless arguments which are not provided with - or -- 
        # 'rank' givens the rank of the arguments as it is read from left to right 
        # on command line
        case ${rank} in
                0) 
                    Str__upcaseFirst value
                    GENAPP__VARS["appname"]="${value}" ;
                    return 0 
                    ;; 
                *) return 1 
                ;;
        esac        

        return 1 
}

Genapp__parseArgs() {
    local argc=0
    local arg_cnt=0

    _log_dbg "Genapp__parseArgs"

    _parseFromArgToVars GENAPP__OPTION_LIST_DESC GENAPP__OPTION_LIST_ARGS GENAPP__OPTION_LIST_ACTI GENAPP__OPTION_LIST_VALS argc arg_cnt "$@"

:<<'EOF'
    # Handle here specific cases e.g. 
    # - raise an error when no arguments at all is supplied
    # - or set up a specific handling with defaults params
    if [ $argc -eq 0 ] ; then
        _susage "missing arguments"
    fi
EOF
    _log_dbg "Genapp__parseArgs argc='$argc' arg_cnt='$arg_cnt'"
}

:<<'EOF'
Callback called for cleaning up app upon signal arising

@param [1] the code with which the app will exit, i.e. the initially caught exit code

EOF

Genapp__cleanup()
{
:<<EOF
    local appName="${__SHELL_CURRENT_APPNAME__}"
    _log "${appName} cleaning up"
EOF
}

Genapp__createFromTemplate()
{
    local src="$1"
    local dst="$2"
    cp "${GENAPP__VARS["MYDIR"]}/$src" "${GENAPP__VARS["appdirname"]}/$dst"
    _log_high "generated ${GENAPP__VARS["appdirname"]}/$dst"
    Genapp__replaceCopyrightNotice "${GENAPP__VARS["appdirname"]}/$dst"
}

Genapp__replaceCopyrightNotice()
{
    sed -i -E "s/Copyright \(c\) 2026 Michel Mehl/Copyright \(c\) $(date +'%Y') ${GENAPP__VARS["author"]}/g" "$1"
    sed -i -E "s/Michel Mehl/${GENAPP__VARS["author"]}/g" "$1"
    sed -i -E "s/michel.mehl@slashetc.fr/${GENAPP__VARS["email"]}/g" "$1"
    sed -i -E "s/Genapp tool/${GENAPP__VARS["appname"]}/g" "$1"
    sed -i -E "s/shell-api and genapp bash app generator/${GENAPP__VARS["appname"]}/g" "$1"
}

Genapp__replaceTemplateKeywords()
{
    local -n __inFilelist=$1
    local appname="${GENAPP__VARS["appname"]}"
    local lowerAppname="$appname"
    local upperAppname="$appname"
    Str__toLower lowerAppname
    Str__toUpper upperAppname

    local url=""
    if [ -z "${GENAPP__VARS["http"]}" ]  ; then
        url=$(echo "https://github.com/%githubid%/%appname%" | sed -E "s#%appname%#${GENAPP__VARS["appdirname"]}#g" | sed -E "s#%githubid%#${GENAPP__VARS["githubid"]}#g")
    fi

    local relPathToShellApiDir="$(realpath --relative-to "${GENAPP__VARS["appdirname"]}" "${GENAPP__VARS["MYDIR"]}/")"
    #_log_vars relPathToShellApiDir
    local file
    for file in "${__inFilelist[@]}" ; do
        sed -i -E "s#%appdirname%#${relPathToShellApiDir}#g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/%appname%/${lowerAppname}/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s#%appurl%#$url#g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/%appdesc%/${GENAPP__VARS["appdesc"]}/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/%author%/${GENAPP__VARS["author"]}/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/%githubid%/${GENAPP__VARS["githubid"]}/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/%email%/${GENAPP__VARS["email"]}/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s#%rootreleasedir%#${GENAPP__VARS["rootreleasedir"]}#g" "${GENAPP__VARS["appdirname"]}/$file"
    done

}

Genapp__replaceGenAppRefsIntoTemplate()
{
    local -n __inFilelist=$1
    local appname="${GENAPP__VARS["appname"]}"
    local lowerAppname="$appname"
    local upperAppname="$appname"
    Str__toLower lowerAppname
    Str__toUpper upperAppname

    local relPathToShellApiDir="$(realpath --relative-to "${GENAPP__VARS["appdirname"]}" "${GENAPP__VARS["MYDIR"]}/")"
    #_log_vars relPathToShellApiDir
    local file
    for file in "${__inFilelist[@]}" ; do
        sed -i -E "s#%SHELL_API_DIR%#${relPathToShellApiDir}#g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/GENAPP__/${upperAppname}__/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/Genapp/${appname}/g" "${GENAPP__VARS["appdirname"]}/$file"
        sed -i -E "s/genapp/${lowerAppname}/g" "${GENAPP__VARS["appdirname"]}/$file"
    done
}

Genapp__generate()
{
    local appname="${GENAPP__VARS["appname"]}"
    local lowerAppname="$appname"
    local upperAppname="$appname"
    Str__toLower lowerAppname
    Str__toUpper upperAppname

    if [ -d "$lowerAppname" ] ; then
        if ! Input__confirm "Folder ${lowerAppname} exists. Do you want to continue and overwrite existing files there?" ; then
            return 1
        fi
    else
        mkdir "$lowerAppname" 
    fi
    GENAPP__VARS["appdirname"]="$lowerAppname"

    # Generate the text files
    #
    # Create version file from scratch
    echo "1.0.0" > "$lowerAppname/VERSION.txt"
    _log_high "generated $lowerAppname/VERSION.txt"

    # Create CHANGELOG file from scratch
    echo "* First release" > "$lowerAppname/CHANGELOG.txt" 
    _log_high "generated $lowerAppname/CHANGELOG.txt"

    # Create examples from templates
    Genapp__createFromTemplate templates/template__EXAMPLES.txt EXAMPLES.txt

    # License file from shell-api own file as template
    Genapp__createFromTemplate LICENSE.txt LICENSE.txt

    # shell-api copyright file as template
    Genapp__createFromTemplate templates/template__COPYRIGHT.txt COPYRIGHT.txt

    # Makefile to create dpkg package
    Genapp__createFromTemplate templates/template__Makefile Makefile
    local filelist=(Makefile)
    Genapp__replaceTemplateKeywords filelist

    # Create the files for the packaging
    mkdir "${GENAPP__VARS["appdirname"]}/pack" &>/dev/null
    cp -r  "${GENAPP__VARS["MYDIR"]}/templates/template_pack"/* "${GENAPP__VARS["appdirname"]}/pack/"
    _log_high "generated ${GENAPP__VARS["appdirname"]}/pack/"
    Genapp__replaceCopyrightNotice "${GENAPP__VARS["appdirname"]}/pack/debian/control"
    filelist=(pack/debian/control)
    Genapp__replaceTemplateKeywords filelist

    # Generate the config file (empty)
    echo "" > "${GENAPP__VARS["appdirname"]}/${lowerAppname}.yml"
    _log_high "generated ${GENAPP__VARS["appdirname"]}/${lowerAppname}.yml"

    # Generate the app itself
    Genapp__createFromTemplate templates/template__app.sh "${lowerAppname}" 
    Genapp__createFromTemplate templates/template__vars.sh "${lowerAppname}__vars.sh" 
    Genapp__createFromTemplate templates/template__options.sh "${lowerAppname}__options.sh" 
    Genapp__createFromTemplate templates/template__help.sh "${lowerAppname}__help.sh" 

    filelist=("${lowerAppname}" "${lowerAppname}__vars.sh" "${lowerAppname}__options.sh" "${lowerAppname}__help.sh")
    Genapp__replaceGenAppRefsIntoTemplate filelist
}

Genapp__main() {
    local allargs=("$@")

    if ! _parseArgs "${allargs[@]}" ; then
            _exit -1 "Failed to parse arguments"
    fi
    if [ -z "${GENAPP__VARS["appname"]}" ] ; then
        Genapp__usage
        _exit -1 "Please specify an application name, starting with an upper case"
    fi

    Genapp__generate 
    #Genapp__test
}

Genapp__test() {
    GENAPP__VARS["author"]="Georges Washington"
    GENAPP__VARS["email"]="georges.washington@whitehouse.org"

    Genapp__generate 

    #testapp/testapp --version 
    #testapp/testapp --help 
    #testapp/testapp --man --verbose 
}

allArgs=("$@")
if _main "${allArgs[@]}" ; then

        if ${GENAPP__VARS["verbose"]} ; then
            _quit "${__SHELL_CURRENT_APPNAME__} has finished."
        else
            _quit ""
        fi

else
        _exit -1 "${__SHELL_CURRENT_APPNAME__} ended with a failure. Please check above messages."
fi



