# FILE: logging.zsh
#
# This file provides a logging facility for stdlib.zsh.

typeset -A _status_codes
_status_codes=(
    usage 2
)
autoload -U colors && colors

: ${LOG_VERBOSE:=0}

if [[ $ZSL_USAGE && $usage_verbose ]]; then
    LOG_VERBOSE=1
fi

_zsl_print_styled() {
    local esc=$'\e['
    local pos=0 mstart mend plen ZPCRE_OP
    local -a codes=()
    local text="$@"
    pcre_compile '\[(\w+?)\]'
    while pcre_match -a codes -n $pos -b -- "$text"; do
        mstart=${ZPCRE_OP/ */}
        mend=${ZPCRE_OP/* /}
        plen=$(($mstart - $pos))
        if (($plen)); then
            echo -n "${text:$pos:$plen}"
        fi
        pos=$mend
        case "${codes[1]}" in
        bold | faint)
            echo -n "$esc${color[${codes[1]}]}m"
            ;;
        cyan | white | yellow | magenta | black | blue | red | green)
            echo -n "${fg[${codes[1]}]}"
            ;;
        reset)
            echo -n "$reset_color"
            ;;
        *)
            echo -n "[!${codes[1]}]"
            ;;
        esac
    done
    plen=$((${#text} - $pos))
    echo -n "${text:$pos:$plen}"
    echo ""
}

_zsl_log_error() {
    _zsl_print_styled "[bold][red]${*}[reset]" >&2
}

_zsl_log_warning() {
    _zsl_print_styled "[bold][yellow]${*}[reset]" >&2
}

_zsl_log_notice() {
    _zsl_print_styled "[bold][magenta]${*}[reset]" >&2
}

_zsl_log_action() {
    _zsl_print_styled "[bold]${*}[reset]" >&2
}

_zsl_log_success() {
    _zsl_print_styled "[bold][green]${*}[reset]" >&2
}

_zsl_log_info() {
    _zsl_print_styled "${*}" >&2
}

_zsl_log_debug() {
    if (($LOG_VERBOSE > 0)); then
        _zsl_print_styled "[cyan]DBG:[reset] [faint]${*}[reset]" >&2
    fi
}

_zsl_msg() {
    local lcmd=_zsl_log_info
    case "$1" in
    -err | -error)
        lcmd=_zsl_log_error
        shift
        ;;
    -warn | -warning)
        lcmd=_zsl_log_warning
        shift
        ;;
    -dbg | -debug)
        lcmd=_zsl_log_debug
        shift
        ;;
    -success)
        lcmd=_zsl_log_success
        shift
        ;;
    -action)
        lcmd=_zsl_log_action
        shift
        ;;
    -notice)
        lcmd=_zsl_log_notice
        shift
        ;;
    -- | -info)
        shift
        ;;
    -*)
        _zsl_log_error "invalid msg type $1"
        shift
        ;;
    esac

    "$lcmd" "$@"
}

msg() {
    _zsl_msg "$@"
}

die() {
    local ec=1
    if [[ $1 =~ "^-[0-9]+$" ]]; then
        ec="${1#-}"
        shift
    elif [[ $1 = -* && -v _status_codes[${1#-}] ]]; then
        ec="${_status_codes[${1#-}]}"
        shift
    fi
    _zsl_msg -error "$*"
    exit $ec
}

echo-run() {
    _zsl_print_styled "+ [bold]${*}[reset]" >&2
    "$@"
    return "$?"
}
