# shellcheck shell=dash

___x_cmd_log_trace(){
    local old_trace_name="${___X_CMD_LOG_TRACE_LINE_LOCAL}"
    ___X_CMD_LOG_TRACE_LINE_LOCAL="$1"

    local new_trace_name="${1:?Provide New Trace}"

    [ -z "$___X_CMD_LOG_TRACE_DEBUGTRIG" ] || { eval [ "\${___X_CMD_LOG__${new_trace_name%%/*}:-2}" -gt 1 ] || ___X_CMD_LOG_DEBUG=1; }
    { [ -n "$___X_CMD_LOG_DEBUG" ] || eval [ "\${___X_CMD_LOG__${new_trace_name%%/*}:-2}" -le 1 ] \&\& [ "\${___X_CMD_LOG__${old_trace_name%%/*}:-2}" -le 1 ]; } || return 0

    if [ -z "$old_trace_name" ] || [ "${1#"$old_trace_name"}" != "$1" ]; then
        ___x_cmd_log_trace_log "${old_trace_name:-/} >>> ${1#"$old_trace_name"/} "
        return
    fi

    local e; local common; local rest="${old_trace_name}"
    local IFS="/"; local i; for i in ${new_trace_name}; do
        e="${rest#"$i"}"
        [ "${e}" != "$rest" ] || break
        common="$common/${i}"
        rest="${e#/}"
    done

    shift
    common="${common#/}"
    if [ "$#" -ne 0 ]; then
        IFS=" "; ___x_cmd_log_trace_log "[${common}] $rest => ${new_trace_name#"$common/"} $*"
    else
        IFS=" "; ___x_cmd_log_trace_log "[${common}] $rest => ${new_trace_name#"$common/"}"
    fi
}

# alias x.trace.dbgtrig=___x_cmd_log_trace_debugtrig
# alias log:trace:dbgtrig=___x_cmd_log_trace_debugtrig
# ___x_cmd_log_trace_debugtrig(){
#     ___X_CMD_LOG_TRACE_DEBUGTRIG=1
# }

# alias x.trace.dbgtrig.stop=___x_cmd_log_trace_debugtrig_stop
# alias log:trace:dbgtrig:stop=___x_cmd_log_trace_debugtrig_stop
# ___x_cmd_log_trace_debugtrig_stop(){
#     ___X_CMD_LOG_TRACE_DEBUGTRIG=
# }


___x_cmd_log_trace_evex(){
    if [ -z "$___X_CMD_LOG_DEBUG" ] && eval [ "\${___X_CMD_LOG__${___X_CMD_LOG_TRACE_LINE_LOCAL%%/*}:-2}" -gt 1 ]; then
        ___x_cmd_evex "$@"
    else
        ___x_cmd_log_trace_log "$*"      # repr $*
        ___x_cmd_evex "$@"
        ___x_cmd_log_trace_log_exit $? "[exit: $code] $*"
    fi
}


___x_cmd_log_trace_time(){
    if [ -z "$___X_CMD_LOG_DEBUG" ] && eval [ "\${___X_CMD_LOG__${___X_CMD_LOG_TRACE_LINE_LOCAL%%/*}:-2}" -gt 1 ]; then
        ___x_cmd_evex "$@"
    else
        local ___x_cmd_log_trace_time_timestamp
        ___x_cmd_log_trace_time_timestamp="$(___x_cmd_cmds date +%s)"
        ___x_cmd_log_trace_log_start "$*"      # repr $*
        ___x_cmd_evex "$@"
        ___x_cmd_log_trace_log_exit $? "[exit: $code] [elapsed: $(($(___x_cmd_cmds date +%s) - ___x_cmd_log_trace_time_timestamp))]: $*"
    fi
}

# Section: log & log_exit
___x_cmd_log_trace_log(){
    if [ -n "$___X_CMD_LOG_C_TF" ] || [ -t 2 ]; then
        printf "\033[7;32m%s: \033[1;7;32m%s\033[0m\n"  "[TRC] <$___X_CMD_LOG_TRACE_LINE_LOCAL>" "$1" >&2
    else
        printf "%s: %s\n"                               "[TRC] <$___X_CMD_LOG_TRACE_LINE_LOCAL>" "$1" >&2
    fi
}

___x_cmd_log_trace_log_start(){
    if [ -n "$___X_CMD_LOG_C_TF" ] || [ -t 2 ]; then
        printf "\033[7;32m%s: \033[1;32m%s\033[0m\n"    "[TRC] <$___X_CMD_LOG_TRACE_LINE_LOCAL>" "$1" >&2
    else
        printf "%s: %s\n"                               "[TRC] <$___X_CMD_LOG_TRACE_LINE_LOCAL>" "$1" >&2
    fi
}

___x_cmd_log_trace_log_exit(){
    local code=$1;  shift
    local color
    if [ "$code" -eq 0 ]; then      color="\033[1;7;36m"
    else                            color="\033[1;7;31m"
    fi

    if [ -n "$___X_CMD_LOG_C_TF" ] || [ -t 2 ]; then
        printf "%s: ${color}%s\033[0m\n"    "[TRC] <$___X_CMD_LOG_TRACE_LINE_LOCAL>" "$1"  >&2
    else
        printf "%s: %s\n"                   "[TRC] <$___X_CMD_LOG_TRACE_LINE_LOCAL>" "$1"  >&2
    fi
}
# EndSection

# echo $___X_CMD_LOG_TRACE_DEBUGTRIG

# f_a_c(){
#     log:trace f/a/c
#     echo "$1"
# }

# f_a_b(){
#     log:trace f/a/b
#     echo "$1"
#     f_a_c 111
# }

# f_a(){
#     log:trace f/a
#     f_a_b 1
#     x:info hi
# }

# f_a
