# Helpers for paths manipulation

clean_path() {
    local path
    local newpath=
    local keepifs=$IFS

    IFS=:
    for path in $PATH; do
        path=${path%/}
        [ -d "$path" ] || continue
        case ":$newpath:" in
        *":$path:"*) continue ;;
        esac
        newpath="${newpath:+${newpath}:}${path}"
    done
    IFS=$keepifs
    PATH=$newpath
}

add_path() {
    local position
    local path
    local add

    for path in $(echo "$@" | tr ':' ' '); do
        case $path in
        -b | --before)
            position=before
            continue
            ;;
        -a | --after)
            position=after
            continue
            ;;
        esac
        echo "$path" | grep -q "^-" && continue
        [ -f "$path" ] && path=$(cd $(dirname "$path") && pwd)
        path=$(cd "$path" 2>/dev/null && pwd)
        [ -z "$path" ] && continue
        [ -d "$path" ] && add="${add:+${add}:}$path"
    done

    case $position in
    before)
        PATH=${add:+${add}:}"$PATH"
        ;;
    *)
        PATH="$PATH"${add:+:${add}}
        ;;
    esac

    # clean_path
}

prepend_path() {
    add_path --before "$@"
}

append_path() {
    add_path --after "$@"
}

# Utility functions for true/false checking
is_true() {
    local lower=${*,,}

    case "$lower" in
    yes | y | on | true | 1) return 0 ;;
    *) return 1 ;;
    esac
}

is_false() {
    local lower=${*,,}

    case "$lower" in
    no | n | off | false | 0) return 0 ;;
    # "") return 0 ;;  # Empty is not false, it's null
    *) return 1 ;; # Unknown is false
    esac
}

is_numeric() {
    echo "$@" | grep -v "\..*\." | grep -Eq "^[0-9\.]*$"
    return $?
}

is_integer() {
    echo "$@" | grep -Eq "^[0-9]+$"
    return $?
}

log() {
    [ -z "$*" ] && return
    local append err

    err=$(echo "$1" | grep -E "^[0-9]+$" || true)
    [ -z "$err" ] || shift

    case "$err" in
    0) COLOR=${GREEN} ;;
    "") COLOR=${YELLOW} ;;
    *)
        COLOR="$RED"
        append=" ($err)"
        ;;
    esac

    [ "${1:-}" = "-n" ] && n="-n" && shift || n=
    [ -n "$*" ] || return
    (
        printf "${COLOR}%s:${STD} %s" "${LOG_PREFIX:-$PGM}" "$*${append:-}"
        is_true "${LOG_TRACE:-no}" && printf " (%s)" "$(ansi_color underline)$(caller | sed "s:$BASE_DIR/*::;")${STD}"
        printf "\n"
    ) >&2
}

yesno() {
    local default=n choice="y/N" answer message

    [ "$1" = "y" ] && default=y && choice="Y/n" && shift
    [ "$1" = "-y" ] && default=y && choice="Y/n" && shift
    [ "$@" ] && message="$@" || message="Answer"
    message="$message ($choice) "
    read -r -p "$message" answer || answer=
    [ "$answer" = "" ] && answer=$default
    answer=$(echo "$answer" | tr "[:upper:]" "[:lower:]")
    [ "$answer" = "y" ] && return 0
    [ "$answer" = "yes" ] && return 0
    return 1
}

readvar() {
    local var varname

    for var in $@; do
        varname=$(echo $var | sed "s/\([a-z]\)\([A-Z]\)/\\1 \\2/g")
        if [ "$AUTOMATIC" = "yes" ]; then
            echo "$varname: ${!var}"
        else
            read -e -p "$varname: " -i "${!var}" $var
        fi
    done
}
