# shellcheck    shell=zsh

# Section: Life Cycle
# DICT_KEYS_SEP=","
# DICT_SEP="-"
___x_cmd_dict_make(){
    local O="${O:?Please provide object name}"
    unset "___X_BASH_DICT_$O"
    ___x_cmd_instance_add "dict" "$O"
    typeset -gA ___X_BASH_DICT_"$O"
}

___x_cmd_dict_clear(){
    local O="${O:?Please provide object name}"
    eval "typeset -gA ___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}"
    for key val in $(eval echo "\"\${(kv)___X_BASH_DICT_$O}\""); do
        printf "%s${DICT_SEP}%s${DICT_SEP}" "${key#*${DICT_KEYS_SEP}}" "$val"
        i=$((i+1))
    done
    printf "%s\n" "$i"
}

___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}[\$DICT_KEYS_SEP\$key]=\"\$val\""
    done
}

# EndSection

# Section: size get put scope remove

___x_cmd_dict_size(){
    : "${O:?Please provide object name}"
    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="$DICT_KEYS_SEP$*"

    local s
    s="$(eval printf %s "\"\${___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="$DICT_KEYS_SEP${key%${DICT_KEYS_SEP}*}"
    eval "___X_BASH_DICT_${O}[\$key]"="\"\$val\"" 2>/dev/null || ___x_cmd_dict_make "$O"; 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 "${DICT_KEYS_SEP}%s${DICT_KEYS_SEP}" "$*")

    local key
    local i=0
    IFS="${DICT_SEP}"

    for key in $(eval printf %s "\"\${(k)___X_BASH_DICT_"$O"[*]}\""); do
        if [[ "$key" == "$s"* ]]; then
            val="$(eval printf "%s\\\\n" "\"\${(v)"___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 "${DICT_KEYS_SEP}%s" "$*")

    IFS="${DICT_SEP}"

    local code=1
    local key
    for key in $(eval printf %s "\"\${(k)"___X_BASH_DICT_$O"[*]}\""); 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 "${DICT_KEYS_SEP}%s" "$*")

    IFS="${DICT_SEP}"

    local code=1
    local key
    for key in $(eval printf %s "\"\${(k)"___X_BASH_DICT_$O"[*]}\""); 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 "\${\!$O[@]}"; do
        if [[ "$key" =~ $s ]]; then
            eval "echo \"___X_BASH_DICT_\$O[\$DICT_KEYS_SEP\$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 "\${\!$O[@]}"; do
        val="$(eval "\${___X_BASH_DICT_\$O[\$DICT_KEYS_SEP\$key]}")"
        eval "$fun"
    done
}

# EndSection
