#!/usr/local/bin/bash

#export PS4='\e[90m+${LINENO} in ${current}: \e[0m'
current=${BASH_SOURCE[0]}

debug.version()              # prints out the hard coded version tag of $This 
{
 console.log "$0 debug version: 20210626 20:45"
}



function step()
{

  { 
      set +x
  } 2>/dev/null

    echo step on level $LOG_LEVEL
    if [ -z "$LOG_LEVEL" ]; then
        LOG_LEVEL=5
        export PS4='\e[90m  ${BASH_SOURCE[0]##*/} -> ${BASH_SOURCE[1]##*/}: ${FUNCNAME[0]}:${LINENO}   - ${BASH_SOURCE[@]##*/} \e[0m'
    fi

  if [ "$STEP_DEBUG" = "ON" ]; then

    echo -e "\e[37m+<-----------------------------------------"
    echo "> function ${FUNCNAME[1]}(" "${BASH_ARGV[@]}" ")  in file: ${BASH_SOURCE[1]}"
    echo -e "> line: ${BASH_LINENO[1]} '${BASH_COMMAND}'\e[0m"

    read -p '' CONT

    if [[ ! "$CONT" = "" ]]; then
      case $CONT in
        h)
            echo "
            h     this help
            e     expands variable in the command
            n     next command full with debug
            ENTER next command

            d     toggle debug messages
            t     trace the stack
            s     continue silently
            c     with debug
            p     print PATH
            ll    list dir
            cd    changing to entered path
            root  tree /root
            home  tree /home
            i     check eamd
            eamd  tree workspace

            cmd   runn command (BE CAREFULL)

            q     exit
                all other commands exit too
            "
            step
            ;;
        s)
            removeTrap
            DEBUG=OFF
            debug.log "DEBUG is OFF"
            set +x
            ;;
        n)
            #removeTrap
            DEBUG=ON
            set -x
            ;;
        x)
            DEBUG=ON
            removeTrap
            set -x
            ;;
        c)
            DEBUG=ON
            removeTrap
            set +x
            ;;
        e)
            echo "> expands to: $(eval echo "$BASH_COMMAND")"
            step
            ;;
        r)
            export STEP_TILL_NEXT_RETURN=ON
            removeTrap
            warn.log "continue till next Return"
            step
            ;;
        t)
            stackTrace
            ;;
        ls)
            ls -al
            step 
            ;;
        d)
            toggleDebug
            step
            ;;
        p)
            console.log "PATH=$PATH"
            step
            ;;
        ll)
            pwd
            ls -alF
            step
            ;;
        root)
            tree -aL 2 /root
            step
            ;;
        home)
            tree -aL 2 /home
            step
            ;;
        eamd)
            tree -aL 2 /$defaultWorkspace/..
            step
            ;;
        i)
            eamd check
            step
            ;;
        cd)
            read -p 'cd to?   >' CD_DIR
            cd $CD_DIR
            step
            ;;
        cmd)
            read -p 'command?  BE CAREFULL >' command
            set -x
            $command
            step
            ;;    
        env)
            read -p 'ENV VARIBALE NAME>' env
            set -x
            echo -e "\e[1;33mexport $env=${!env}\e[0m"
            step
            ;;          
        *)
            set +x
            warn.log "FORCE EXIT because of command: $CONT"
            exit 0
      esac
    #else
      #echo "ENTER: continue"
    fi
  #else
    #echo "Step Debug is $STEP_DEBUG"
  fi
 
  if [ "$LOG_LEVEL" -gt "4" ]; then
    set -x
  else
    { 
      set +x
    } 2>/dev/null
  fi
    
}

function stackTrace() {
            i=0;
            #for (( i=0; i<=${#BASH_LINENO[@]}; i++)); do
            echo -e "\e[1;37m" 
            for l in ${BASH_LINENO[@]}; do
                printf "i: %2d  line: %6d  function: %-20s  file: %-30s   args: " "$i" "$l" "${FUNCNAME[$i]}()" "${BASH_SOURCE[$i]}"
                echo "\"${BASH_ARGV[@]}\" and \"$@\""
                ((i++))
            done
            echo -e "\e[0m"
            step
}

function stepDebugger() {

  if [ "$1" = "OFF" ]; then
      removeTrap
  fi
  if [ "$1" = "ON" ]; then
      export STEP_DEBUG=ON
  fi

}

function setTrap() {
  #echo "trap DEBUG set to step"

  #export PS4='\e[90m+${LINENO}: '

  trap step DEBUG
  #set -e
  trap 'onError ${?}' ERR
  trap 'onReturn ${?}' RETURN
  trap 'onExit  ${?}' EXIT 
}

function checkTrace() {
    case $- in
        *x* ) 
            echo "Trace is ON"
            export TRACE=ON
            ;;
        * )               
            echo "Trace is OFF"
            export TRACE=OFF;
            ;;
    esac
}

function setTrace() {
    case $TRACE in
        ON ) 
            set -x
            export TRACE=ON
            ;;
        * )               
            set +x
            export TRACE=OFF
            ;;
    esac
}


function removeTrap() {
  export STEP_DEBUG=OFF
  #trap - DEBUG ERR RETURN EXIT
}

function ckeckDebug() {
    setTrap

    source $OOSH_PATH/log

#   if [[ "$(basename -- "$0")" == "debug" ]]; then
#     # called
#     if [ -n "$1" ]; then
#         export DEBUG=$1
#         config save
#     fi
#     warn.log "debug has no effect if it was not sourced with . debug"
#   else
#     # sourced
#     debug.log "debug was sourced from: $0"
#     if [[ "$(basename -- "$0")" == "-bash" ]]; then
#        debug.log "sourced from: bash"
#        DEBUG=$1
#     fi
#   fi


#   if [ -n "$DEBUG" ]; then
#     #echo "DEBUG was $DEBUG, and is now ON"
#     case $DEBUG in
#       X)
#         set -x
#         ;;
#       OFF)
#         unset DBEUG
#         ;;
#       *)
#         export DEBUG=ON
#     esac
#   #else
#     #echo "DEBUG is $DEBUG"
#   fi
}

function toggleDebug() {
    if [ "ON" = "$DEBUG" ]; then 
        DEBUG=OFF
        #set +x
    else
        DEBUG=ON
    fi
    warn.log "Toggeld DEBUG to $DEBUG"
}

function onReturn() {
    debug.log "function ${FUNCNAME[1]} returned with code: $1 and RETURN=$2"
    if [ "$0" = "$2" ]; then
        #do not stop when in this $0 debug file $2
        return 0
    fi
    
    if [ "ON" = "$STEP_TILL_NEXT_RETURN" ]; then 
        STEP_TILL_NEXT_RETURN=OFF
        export STEP_DEBUG=ON
        #set +x
    fi
    #current.context
#   if [ -z "$2" ]; then
#     RETURN=$2
#   fi
}

function onError() {
  #echo -e "\e[1;31m   line: ${BASH_LINENO[2]} '${BASH_COMMAND[2]}'\e[0m"

  if [ "$1" = "1" ]; then
    return
  fi

    error.log         "function ${FUNCNAME[1]} in line: ${BASH_LINENO[2]} returned with ERROR code: $1"
    if [ "ON" = "$DEBUG" ]; then
      export STEP_DEBUG=
      stackTrace
      export STEP_DEBUG=ON
    fi
}

function onExit() {
  debug.log "exiting"
}

debug.log() {
    if [ "$LOG_LEVEL" -gt "3" ]; then
        #test -t 1 && tput setf 7     
        echo -e "\e[1;36m- $@\e[0m"
        #echo "- $@"
        #test -t 1 && tput sgr0 # Reset terminal
    fi
}

console.log() {
    #test -t 1 && tput bold; tput setf 7                                            ## white bold
    if [ "$LOG_LEVEL" -gt "2" ]; then
        echo -e "\e[0m>  $@"
    fi
    #test -t 1 && tput sgr0 # Reset terminal
}
error.log() {
    err.log "$@"
}
err.log() {
    #test -t 1 && tput bold; tput setf 4  
    #echo "ERROR>  $@"
    echo -e "\e[1;31mERROR> $@\e[0m"    
    #test -t 1 && tput sgr0 # Reset terminal
    if [ "ON" = "$DEBUG" ]; then 
        export STEP_DEBUG=ON
    fi   
}
warn.log() {
    #test -t 1 && tput bold; tput setf 6
    if [ "$LOG_LEVEL" -gt "1" ]; then
        echo -e "\e[1;33m> WARNING $@\e[0m"                                    ## yellow
    fi
    #test -t 1 && tput sgr0 # Reset terminal
}
stop.log() {
    if [ "$LOG_LEVEL" -gt "4" ]; then
        #test -t 1 && tput bold; tput setf 6                                    ## green
        #echo "BREAKPOINT> $@"
        echo -e "\e[1;32mBREAKPOINT> $@\e[0m" 
        #test -t 1 && tput sgr0 # Reset terminal
        export STEP_DEBUG=ON
    fi  
}
success.log() {
    #if [ "ON" = "$DEBUG" ]; then 
    if [ "$LOG_LEVEL" -gt "1" ]; then
        echo -e "\e[1;32mSUCCESS> $@\e[0m" 
    fi
    #fi  
}

ckeckDebug "$@"

#`debug.version
#setTrap
