# shellcheck shell=dash

___x_cmd_ldict___main(){
    local op="$1"; shift
    case "$op" in
        put)        ___x_cmd_ldict_put "$@"     ;;
        unshift)    ___x_cmd_ldict_unshift "$@" ;;
        rm)         ___x_cmd_ldict_rm "$@"      ;;
        has)        ___x_cmd_ldict_has "$@"     ;;
        get)        ___x_cmd_ldict_get "$@"     ;;
        get_)       ___x_cmd_ldict_get_ "$@"    ;;
        keys)       ___x_cmd_ldict_keys "$@"    ;;
        vals)       ___x_cmd_ldict_vals "$@"    ;;
        load)       ___x_cmd_ldict_load "$@"    ;;
        dump)       ___x_cmd_ldict_dump "$@"    ;;
        print)      ___x_cmd_ldict_print "$@"   ;;
        *)
            printf "Show help for ldict\n" >&2
            return 1
    esac
}

# alias ldict="___x_cmd_ldict"

# ___X_CMD_LDICT_SEP="$(printf "\001")"
# ___X_CMD_LDICT_KVSEP="$(printf "\002")"

___X_CMD_LDICT_SEP="$___X_CMD_UNSEENCHAR_003"
___X_CMD_LDICT_KVSEP="$___X_CMD_UNSEENCHAR_004"

___x_cmd_ldict_unshift(){
    local name="${1:?Provide dict name}"
    local key="${2:?Provide key}"
    local value="${3:?Provide value}"

    ___x_cmd_ldict_rm "$name" "$key" || true

    eval "___X_CMD_LDICT_${name}=\"\${___X_CMD_LDICT_SEP}\${key}\${___X_CMD_LDICT_KVSEP}\${value}\${___X_CMD_LDICT_${name}:-\${___X_CMD_LDICT_SEP}}\""
}

___x_cmd_ldict_put(){
    local name="${1:?Provide dict name}"
    local key="${2:?Provide key}"
    local value="${3:?Provide value}"

    ___x_cmd_ldict_rm "$name" "$key" || true

    eval "___X_CMD_LDICT_${name}=\"\${___X_CMD_LDICT_${name}:-\${___X_CMD_LDICT_SEP}}\${key}\${___X_CMD_LDICT_KVSEP}\${value}\${___X_CMD_LDICT_SEP}\""
}



___x_cmd_ldict_rm(){
    local name="${1:?Provide dict name}"
    local key="${2:?Provide key}"

    local tmp
    eval "tmp=\"\${___X_CMD_LDICT_${name}#*\${___X_CMD_LDICT_SEP}\${key}\${___X_CMD_LDICT_KVSEP}*\${___X_CMD_LDICT_SEP}}\""
    if eval [ \"\$tmp\" != \"\$"___X_CMD_LDICT_${name}"\" ]; then
        eval "___X_CMD_LDICT_${name}=\"\${___X_CMD_LDICT_${name}%%\${___X_CMD_LDICT_SEP}\${key}\${___X_CMD_LDICT_KVSEP}*}\${___X_CMD_LDICT_SEP}\${tmp}\""
        return 0
    fi
    return 1
}

___x_cmd_ldict_has(){
    local name="${1:?Provide dict name}"
    local key="${2:?Provide key}"

    local tmp
    eval "tmp=\"\${___X_CMD_LDICT_${name}#*\${___X_CMD_LDICT_SEP}\${key}\${___X_CMD_LDICT_KVSEP}*\${___X_CMD_LDICT_SEP}}\""
    eval [ \"\$tmp\" != \"\$"___X_CMD_LDICT_${name}"\" ]
}

___x_cmd_ldict_get(){
    local ___X_CMD_LDICT_GET_
    ___x_cmd_ldict_get_ "$@" || return 1
    printf "%s" "$___X_CMD_LDICT_GET_"
}

___x_cmd_ldict_get_(){
    local name="${1:?Provide dict name}"
    local key="${2:?Provide key}"

    local tmp

    eval "tmp=\"\${___X_CMD_LDICT_${name}#*\${___X_CMD_LDICT_SEP}\${key}\${___X_CMD_LDICT_KVSEP}}\""

    if eval [ \"\$tmp\" != \"\$"___X_CMD_LDICT_${name}"\" ]; then
        ___X_CMD_LDICT_GET_="${tmp%%${___X_CMD_LDICT_SEP}*}"
    else
        ___X_CMD_LDICT_GET_=
        return 1
    fi
}

___x_cmd_ldict_keys(){
    local name="${1:?Provide dict name}"
    eval printf \"%s\" \"\$"___X_CMD_LDICT_${name}"\" | ___x_cmd_cmds_awk -v RS="$___X_CMD_LDICT_SEP" -v FS="${___X_CMD_LDICT_KVSEP}" '
NR!=1{
    print $1
}'
}

___x_cmd_ldict_vals(){
    local name="${1:?Provide dict name}"
    eval printf \"%s\" \"\$"___X_CMD_LDICT_${name}"\" | ___x_cmd_cmds_awk -v RS="$___X_CMD_LDICT_SEP" -v FS="${___X_CMD_LDICT_KVSEP}" '
NR!=1{
    print $2
}'
}



___x_cmd_ldict_load(){
    local name="${1:?Provide dict name}"
    local file="${2:?Provide file}"
    local _line
    [ -f "$file" ] || return $?
    while read -r _line; do
        [ -n "$_line" ] || continue
        ___x_cmd_ldict_put "$name" "${_line%=*}" "${_line#*=}"
    done < "$file"
}

___x_cmd_ldict_dump(){
    local name="${1:?Provide dict name}"
    if [ -z "$2" ]; then
        eval printf \"%s\" \"\$"___X_CMD_LDICT_${name}"\"
    else
        eval "$2=\"\$___X_CMD_LDICT_${name}\""
    fi
}

___x_cmd_ldict_print(){
    local name="${1:?Provide dict name}"
    local ofs="${2:-"="}"
    eval printf \"%s\" \"\$"___X_CMD_LDICT_${name}"\" | ___x_cmd_cmds_awk -v ofs="$ofs" -v RS="$___X_CMD_LDICT_SEP" -v FS="${___X_CMD_LDICT_KVSEP}" '
NR!=1{
    print $1 ofs $2
}'
}
