# shellcheck shell=bash

# Section: Life Cycle

___x_cmd_dict_make(){
    local O="${O:?Please provide object name}"
    ___x_cmd_instance_add "dict" "$O"
    unset "___X_BASH_DICT_$O"
    eval "declare -gA ___X_BASH_DICT_${O}"
    eval "___X_BASH_DICT_$O=()"
}

# O=b dload "$( a.dump | dgrep "abc" | dgerp "abc" )"

___x_cmd_dict_clear(){
    local O="${O:?Please provide object name}"
    eval "declare -A ___X_BASH_DICT_${O}=()"
}

___x_cmd_dict_dump(){
    local O="${O:?Please provide object name}"
    local key
    local val
    local i=0

    IFS="${DICT_SEP}"
    local sss
    sss="$(eval echo "\"\${!___X_BASH_DICT_${O}[*]}\"")"

    for key in $sss; do
        val="$(eval echo "\"\${___X_BASH_DICT_${O}[\"\$key\"]}\"")"
        printf "%s${DICT_SEP}%s${DICT_SEP}" "$key" "$val"
        i=$((i+1))
    done

    printf "%s\n" "$i"
}

# bash 4 means we 'read -d' is available
___x_cmd_dict_load(){
    local O="${O:?Please provide object name}"
    ___x_cmd_dict_make "$O"
    local key
    local val
    while :; do
        read -d "${DICT_SEP}" -r key || return 0
        read -d "${DICT_SEP}" -r val || return 0
        eval "___X_BASH_DICT_${O}[\"\$key\"]=\"\$val\""
    done
}

# EndSection

# Section: size get put scope remove

___x_cmd_dict_size(){
    : "${O:?Please provide object name}"
    # printf "%s\n" "$(eval "\$$O[#@]")"
    eval printf "%s\\\\n" "\"\${#___X_BASH_DICT_${O}[@]}\""
}

___x_cmd_dict_get(){
    if [ -z "$O" ]; then
        ___x_cmd_dict___pget "$@"
        return
    fi

    : "${O:?Please provide object name}"
    local IFS="${DICT_KEYS_SEP}"
    local key="$*"

    local s
    s=$(eval printf "%s\\\\n" "\${___X_BASH_DICT_${O}[\"\$key\"]}")
    if [ -n "$s" ]; then
        echo "$s"
    else
        return 1
    fi
}

___x_cmd_dict_put(){
    if [ -z "$O" ]; then
        ___x_cmd_dict___pput "$@"
        return
    fi

    : "${O:?Please provide object name}"
    local IFS="${DICT_KEYS_SEP}"
    local key="$*"
    local val="${key##*${DICT_KEYS_SEP}}"
    key="${key%${DICT_KEYS_SEP}*}"

    if [ -z "$(eval "declare -p ___X_BASH_DICT_${O}" 2> /dev/null)" ]; then
        ___x_cmd_dict_make "$O"
    fi

    eval "___X_BASH_DICT_${O}[\"\$key\"]=\"\$val\""
}

# Not universal enough
___x_cmd_dict_scope(){
    if [ -z "$O" ]; then
        ___x_cmd_dict___pscope "$@"
        return
    fi

    : "${O:?Please provide object name}"
    local IFS="${DICT_KEYS_SEP}"
    local s
    s=$(printf "%s${DICT_KEYS_SEP}" "$*")

    local key
    local i=0
    IFS="${DICT_SEP}"
    local sss
    sss="$(eval echo "\"\${!___X_BASH_DICT_${O}[*]}\"")"

    for key in $sss; do
        # echo "!!! $key" >&2
        if [[ "$key" == "$s"* ]]; then
            val="$(eval echo "\"\${___X_BASH_DICT_${O}[\$key]}\"")"
            printf "%s${DICT_SEP}%s${DICT_SEP}" "${key#$s}" "$val"
            i=$((i+1))
        fi
    done
    printf "%s\n" "$i"
}

___x_cmd_dict_remove(){
    if [ -z "$O" ]; then
        ___x_cmd_dict___premove "$@"
        return
    fi

    : "${O:?Please provide object name}"
    local IFS="${DICT_KEYS_SEP}"
    local s
    s=$(printf "%s\n" "$*")

    IFS="${DICT_SEP}"
    local sss
    sss="$(eval echo "\"\${!___X_BASH_DICT_${O}[*]}\"")"

    local code=1
    local key
    for key in $sss; do
        if [[ "$key" = "$s" ]]; then
            eval "unset ___X_BASH_DICT_${O}[\'\$key\']"
            code=0
        fi
    done
    return "$code"
}

# EndSection

# Section: drop grep iter

___x_cmd_dict_drop(){
    if [ -z "$O" ]; then
        ___x_cmd_dict___pdrop "$@"
        return
    fi

    : "${O:?Please provide object name}"
    local IFS="${DICT_KEYS_SEP}"
    local s
    s=$(printf "%s\n" "$*")

    IFS="${DICT_SEP}"
    local sss
    sss="$(eval echo "\"\${!___X_BASH_DICT_${O}[*]}\"")"

    local code=1
    local key
    for key in $sss; do
        if [[ "$key" =~ $s ]]; then
            eval "unset ___X_BASH_DICT_${O}[\'\$key\']"
            code=0
        fi
    done
    return "$code"
}


___x_cmd_dict_grep(){
    if [ -z "$O" ]; then
        ___x_cmd_dict___pgrep "$@"
        return
    fi

    : "${O:?Please provide object name}"
    local IFS="${DICT_KEYS_SEP}"
    local s
    s=$(printf "%s${DICT_KEYS_SEP}" "$*")

    for key in eval "\${\!___X_BASH_DICT_${O}[@]}"; do
        if [[ "$key" =~ $s ]]; then
            eval "echo \"\___X_BASH_DICT_${O}[\$key]\""
            break
        fi
    done
}

___x_cmd_dict_grepr(){
    ___x_cmd_dict_grep "$@"
}

___x_cmd_dict_iter(){
    local fun="$*" # "$1 \"\$key\" \"\$val\""
    if [ "$#" -eq 1 ] && command -v "$1"; then
        fun="$1 \"\$key\" \"\$val\""
    fi

    : "${O:?Please provide object name}"

    local key
    local val

    for key in eval "\${\!___X_BASH_DICT_${O}[@]}"; do
        val="$(eval "\${\___X_BASH_DICT_${O}[\$key]}")"
        eval "$fun"
    done
}

# EndSection
