library.bash

#!/usr/bin/env bash

##
# @arg directory to source internal bash scripts from 
function source_files(){
    local f
    for f in "$1/"*".bash";do
        source "$f"
    done
}

function debug(){
    local uncomment_this; #and comment the msg to disable debugging
    # debug_str="$1"
    # msg "${cDebug}${debug_str}:${cOff} ${@:2}"
}

dir="$( dirname "${BASH_SOURCE[0]}" )"
IMPORTS=()
useGitBentHelpCache=true

source_files "$dir/lib"

function library_run(){
    source_files "$codeDir/lib"
    # Provide clear starting point for library output
    line_break;
    # run core upload
    run $@
    msg ""
}


function import(){
    imp="${1/\//-}"
    imp="${imp%%-}"
    debug "try import" "$imp" 
    existing="${IMPORTS["$imp"]}"
    if [[ "$existing" != "$imp" ]];then
        file="${codeDir}/${1}.bash"
        IMPORTS["$imp"]="$imp"
        if [[ -f "$file" ]];then
            source "$file"
            return 0
        else
            return 1
        fi
    fi
    return 0
}

function is_function(){
    local func
    local TYPE
    func="$1";
    TYPE=`LC_ALL=C type -t "${func}"`;
    debug "is_function" "name:${1} ++"
    if [[ -n $TYPE && $TYPE == 'function' ]]; then
        return 0;
    fi

    return 1;
}

function run(){
    debug "run" "start"
    local -a at
    # initialize
    cmd_group="$1";
    at=("${@}")
    aliasList=()
    al=""

    debug "  run" "args: ${at[@]}"
    debug "  run" "group: $cmd_group" 


    if [[ "$1" != "help" && "$2" == "help" ]];then
        debug "  run" "help:$1"
        help_mode="run"
        run help "$1"
        return;
    fi

    # Check if command group's file exists, run as core group
    if ! import "core/${cmd_group}"; then
        debug "  run" "group not found"
        run core ${at[@]}
        return
    fi

    ## build alias list
    aliases_func="${cmd_group}_aliases"
    if is_function "$aliases_func";then
        $aliases_func aliasList
    else
        aliasList=()
    fi

    ## Check first arg after command group for an alias
    for al in "${aliasList[@]}";do
        line="$al"
        alternate="${al%%:*}"
        target="${al##*:}"

        if [[ "$2" == "$alternate" ]];then
            at=("$target" "${at[@]:2}")
            debug "  run alias" "new_args: ${at[@]}"
            run ${at[@]}

            return
        fi
    done

    ## Preparing the command
    len="${#at[@]}"
    args="${at[@]}"

    debug "all args" "${at[@]}"
    debug "all args" "${len}"
    while [[ $len -ge 1 ]]; do
        testCommand=""
        # testCommand="${at[@]:0:1}_";
        i=0
        while [[ $i -lt $len ]];do
            testCommand="${testCommand}${at[@]:$i:1}_"
            i=$(( i + 1 ))
        done
        testCommand="${testCommand%_}"

        debug "testcommand" "$testCommand"
        debug "length" "$len"
        if is_function "$testCommand";then
            cmd="$testCommand"
            hits=$tries
            args="${at[@]:$len}"
            break;
        fi

        len=$(( len - 1 ))

    done

    if [[ -z "${cmd}" ]];then
        msg "${cMistake}[${at[@]:1:1}] is not a command${cOff}"
        msg
        debug "" "run help"
        run "help"
    else
        debug "  run (execute)" "cmd: $cmd   args:${args[@]}"
        $cmd ${args[@]}
    fi
}