# Author:       Li Junhao           l@x-cmd.com
# shellcheck    shell=sh            disable=SC3043,SC2164,SC2034     # xrc

# license:      GPLv3

xrc arg
___x_cmd_sdict(){
    local X_help_cmd='x help -m sdict'; help:arg:parse
    arg:init sdict 'x sdict -h'
    local op="$1"; shift
    case "$op" in
        put)        ___x_cmd_sdict_put "$@" ;;
        unshift)    ___x_cmd_sdict_unshift "$@" ;;
        rm)         ___x_cmd_sdict_rm "$@" ;;
        has)        ___x_cmd_sdict_has "$@" ;;
        get)        ___x_cmd_sdict_get "$@" ;;
        get_)       ___x_cmd_sdict_get_ "$@" ;;
        keys)       ___x_cmd_sdict_keys "$@" ;;
        load)       ___x_cmd_sdict_load "$@" ;;
        dump)       ___x_cmd_sdict_dump "$@" ;;
        print)      ___x_cmd_sdict_print "$@" ;;
        *)          help:show:ret:64
    esac
}

# alias sdict="___x_cmd_sdict"

# ___X_CMD_SDICT_SEP="$(printf "\001")"
# ___X_CMD_SDICT_KVSEP="$(printf "\002")"

___X_CMD_SDICT_SEP="$___X_CMD_UNSEENCHAR_003"
___X_CMD_SDICT_KVSEP="$___X_CMD_UNSEENCHAR_004"

___x_cmd_sdict_unshift(){
    local name="$1"
    local key="$2"
    local value="$3"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    [ -n "$key" ]   || M='Please provide dict key'      arg:ret:64
    [ -n "$value" ] || M='Please provide dict value'    arg:ret:64

    ___x_cmd_sdict_rm "$name" "$key"

    eval "${name}=\"\${___X_CMD_SDICT_SEP}\${key}\${___X_CMD_SDICT_KVSEP}\${value}\${${name}:-\${___X_CMD_SDICT_SEP}}\""
}

___x_cmd_sdict_put(){
    local name="$1"
    local key="$2"
    local value="$3"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    [ -n "$key" ]   || M='Please provide dict key'      arg:ret:64
    [ -n "$value" ] || M='Please provide dict value'    arg:ret:64

    ___x_cmd_sdict_rm "$name" "$key"

    eval "${name}=\"\${${name}:-\${___X_CMD_SDICT_SEP}}\${key}\${___X_CMD_SDICT_KVSEP}\${value}\${___X_CMD_SDICT_SEP}\""
}

___x_cmd_sdict_rm(){
    local name="$1"
    local key="$2"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    [ -n "$key" ]   || M='Please provide dict key'      arg:ret:64

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

___x_cmd_sdict_has(){
    local name="$1"
    local key="$2"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    [ -n "$key" ]   || M='Please provide dict key'      arg:ret:64

    local tmp
    eval "tmp=\"\${${name}#*\${___X_CMD_SDICT_SEP}\${key}\${___X_CMD_SDICT_KVSEP}*\${___X_CMD_SDICT_SEP}}\""
    eval [ \"\$tmp\" != \"\$"${name}"\" ]
}

___x_cmd_sdict_get(){
    local ___X_CMD_SDICT_GET_
    ___x_cmd_sdict_get_ "$@" || return 1
    printf "%s" "$___X_CMD_SDICT_GET_"
}

___x_cmd_sdict_get_(){
    local name="$1"
    local key="$2"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    [ -n "$key" ]   || M='Please provide dict key'      arg:ret:64

    local tmp

    eval "tmp=\"\${${name}#*\${___X_CMD_SDICT_SEP}\${key}\${___X_CMD_SDICT_KVSEP}}\""

    if eval [ \"\$tmp\" != \"\$"${name}"\" ]; then
        ___X_CMD_SDICT_GET_="${tmp%%${___X_CMD_SDICT_SEP}*}"
        x_="${___X_CMD_SDICT_GET_}"
    else
        ___X_CMD_SDICT_GET_=
        x_=
        return 1
    fi
}

___x_cmd_sdict_keys(){
    local name="$1"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    eval printf \"%s\" \"\$"${name}"\" | ___x_cmd_cmds_awk -v RS="$___X_CMD_SDICT_SEP" -v FS="${___X_CMD_SDICT_KVSEP}" '
NR!=1{
    print $1
}'
}


___x_cmd_sdict_load(){
    local name="$1"
    local file="$2"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    [ -n "$file" ]  || M='Please provide file'          arg:ret:64
    local _line
    [ -f "$file" ] || return
    while read -r _line; do
        [ -n "$_line" ] || continue
        ___x_cmd_sdict_put "$name" "${_line%=*}" "${_line#*=}"
    done < "$file"
}

___x_cmd_sdict_dump(){
    local name="$1"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    if [ -z "$2" ]; then
        eval printf \"%s\" \"\$"${name}"\"
    else
        eval "$2=\"\$${name}\""
    fi
}

___x_cmd_sdict_print(){
    local name="$1"
    [ -n "$name" ]  || M='Please provide dict name'     arg:ret:64
    eval printf \"%s\" \"\$"${name}"\" | ___x_cmd_cmds_awk -v RS="$___X_CMD_SDICT_SEP" -v FS="${___X_CMD_SDICT_KVSEP}" '
NR!=1{
    print $1 "=" $2
}'
}


xrc setmain ___x_cmd_sdict
