# Author:       Li Junhao       l@x-cmd.com
# shellcheck    shell=dash      disable=SC2016
# license:      GPLv3

___x_cmd_humantime___main(){
    [ $# -gt 0 ]        ||  set -- auto
    local op="$1";          shift
    case "$op" in
        -h|--help)          ___x_cmd help -m humantime ;    return 0 ;;
        tosec|tosec_|toms|toms_|in|auto|op)
                            "___x_cmd_humantime_${op}"      "$@" ;;

        fromsec|sec)        ___x_cmd_humantime_fromsec      "$@" ;;
        fromsec_|sec_)      ___x_cmd_humantime_fromsec_     "$@" ;;

        gt|ge|lt|le|eq)     ___x_cmd_humantime_op  "-${op}" "$@" ;;

        *)                  ___x_cmd_humantime_auto   "$op" "$@" ;;
    esac
}

___x_cmd_humantime_auto(){
    [ $# -gt 0 ] || set -- "${EPOCHSECONDS:-"$( ___x_cmd date timestamp )"}"

    case "$1" in -h|--help) ___x_cmd help -m humantime auto "$@" ; return 0 ;; esac

    if ___x_cmd is int "$1"; then
        ___x_cmd_humantime_fromsec  "$1"
    else
        ___x_cmd_humantime_tosec    "$1"
    fi
}

___x_cmd_humantime_fromsec(){
    [ $# -gt 0 ] || set -- --help
    case "$1" in
        -h|--help)  ___x_cmd help -m humantime sec "$@" ; return 0 ;;
    esac
    local x_
    ___x_cmd_humantime_fromsec_ "$@" || return $?
    printf "%s\n" "$x_"
}

___x_cmd_humantime_fromsec_(){
    local arg="${1:?Provide second argument}"
    local frac=""
    case "$arg" in
        *.*)    frac="${arg#*.}"; frac="${frac:+".$frac"}";
                arg="${arg%%.*}" ;;
    esac

    local res
    x_=""

    res="$(( arg % 60 ))"
    [ -z "$res" ] || x_="${res}${frac}s${x_}"
    arg="$((arg / 60))"
    [ "$arg" -gt 0 ] || return 0

    res="$(( arg % 60 ))"
    [ -z "$res" ] || x_="${res}m${x_}"
    arg="$(( arg / 60 ))"
    [ "$arg" -gt 0 ] || return 0

    res="$(( arg % 24 ))"
    [ -z "$res" ] || x_="${res}h${x_}"
    arg="$(( arg / 24 ))"
    [ "$arg" -gt 0 ] || return 0

    x_="${arg}d${x_}"
}


___x_cmd_humantime_tosec(){
    [ $# -gt 0 ] || set -- --help
    case "$1" in
        -h|--help)  ___x_cmd help -m humantime tosec "$@" ; return 0 ;;
    esac
    local x_
    ___x_cmd_humantime_tosec_ "$@" || return $?
    printf "%s\n" "$x_"
}

if [ "$___X_CMD_SHELL" = zsh ]; then
    . "$___X_CMD_ROOT_MOD/humantime/lib/zsh"
else
    . "$___X_CMD_ROOT_MOD/humantime/lib/nonzsh"
fi

___x_cmd_humantime_toms(){
    [ $# -gt 0 ] || set -- --help
    case "$1" in
        -h|--help)  ___x_cmd help -m humantime toms "$@" ; return 0 ;;
    esac
    local x_
    ___x_cmd_humantime_toms_ "$@" || return $?
    printf "%s\n" "$x_"
}

___x_cmd_humantime_toms_(){
    ___X_CMD_HUMANTIME_UNIT=ms ___x_cmd_humantime_tosec_ "$@"
}

___x_cmd_humantime_op(){
    local op="$1"

    local ret=""
    local x_=""
    while [ $# -gt 0 ]; do
        ___x_cmd_humantime_tosec_ "$1"
        ret="${ret} ${x_} "
        shift
    done

    eval set -- "$ret"

    while [ $# -ge 2 ]; do
        [ "$1" "$op" "$2" ]   ||  return 1
        shift
    done
}

___x_cmd_humantime_in(){
    [ $# -gt 0 ] || set -- --help
    case "$1" in
        -h|--help)  ___x_cmd help -m humantime in "$@" ; return 0 ;;
    esac
    local date=${1:?Provide human time unit}; shift
    local x_
    ___x_cmd_humantime_tosec_ "$date" || return $?

    local i; for i in "$@"; do
        if [ "$i" -ge "$x_" ]; then
            x:debug "Expect within $date($x_) but get $i"
            return 1
        fi
    done
}
