# Author:       Li Junhao   l@x-cmd.com     # xrc
# shellcheck    shell=sh    disable=SC2039,SC3043
# TODO: Honor set-cookie

# #1: path; #2 data
# TODO: next time review

___x_cmd_http_download_request(){
    local IFS=" "
    local X=${X:-GET}
    local paths
    paths="$(___x_cmd_http_cd path "$1")"

    local header_filepath
    header_filepath="$(___x_cmd_http_resp header_filepath)"
    ___x_cmd_cmds_mkdir -p "${2%/*}"
    http:debug "http request data:$(______x_cmd_http_qs_dump curl)"
    http:debug curl -Lo -D "$header_filepath" -X "$X" "$(______x_cmd_http_qs_dump curl)" "$(___x_cmd_http_header_dump curl)" --output "$2" "$paths"
    eval curl -Lo -D "$header_filepath" -X "$X" --output "$2"  "$(______x_cmd_http_qs_dump curl)" "$(___x_cmd_http_header_dump curl)" "$paths" 2>/dev/null
    local a b c
    read -r a b c <<A
    "$(___x_cmd_cmds_cat "$header_filepath")"
A
    if [ -n "$b" ] && [ "$b" -ge 200 ] && [ "$b" -le 303 ]; then
        return 0
    fi

    http:error "HttpCode is $b, Code is 1"
    return 1
}

___x_cmd_http_request() {
    local IFS=" "
    local X="${X:-GET}"
    local data="${2:-"$D"}"

    local paths
    paths="$(___x_cmd_http_cd path "$1")"
    if [ -z "$data" ]; then
        data="$(___x_cmd_http_body dump json "")"
    fi
    local tmp
    tmp=$(mktemp)
    if [ "$data" = "-" ];then
        ___x_cmd_cmds_rm "$tmp"
        tmp="$data"
    else
        printf "%s" "$data" >"$tmp"
    fi
    # TODO: Display the data if only if body is text and data is NOT a lot
    # http:debug "body is: $data"
    # [ -n "$DEBUG" ] && echo "body is: $data" >&2

    local header_filepath data_filepath
    header_filepath="$(___x_cmd_http_resp header_filepath)"
    data_filepath="$(___x_cmd_http_resp body_filepath)"
    status_filepath="$(___x_cmd_http_resp status_filepath)"

    if [ "$X" = GET ] || [ "$X" = DELETE ] || [ "$X" = HEAD ]; then
        http:debug "http request data:$(______x_cmd_http_qs_dump curl)"
        http:debug curl -D "$header_filepath" -X "$X" "$(______x_cmd_http_qs_dump curl)" "$(___x_cmd_http_header_dump curl)" "$paths"
        eval "curl -D $header_filepath -X $X $(______x_cmd_http_qs_dump curl) -o $data_filepath -w \"%{http_code}\" $(___x_cmd_http_header_dump curl) \"$paths\" 1>$status_filepath" 2>/dev/null #2>(http:debug)
    else
        http:debug curl -D "$header_filepath" -X "$X" "$(___x_cmd_http_header_dump curl)"  -o "$data_filepath" -w "%{http_code}" -d "@$tmp" "$paths" "1 > $status_filepath 2>/dev/null"
        eval "curl -D $header_filepath -X $X $(___x_cmd_http_header_dump curl) -o $data_filepath -w \"%{http_code}\" -d @$tmp \"$paths\" 1> $status_filepath 2>/dev/null" #2>(http:debug)
    fi
    [ "$tmp" != "-" ] && ___x_cmd_cmds_rm "$tmp"

    http:debug "Response Header is: $(___x_cmd_cmds_cat "$header_filepath")"

    local status_code; status_code="$(___x_cmd_cmds_cat "$status_filepath")"
    if [ -n "$status_code" ] && [ "$status_code" -ge 200 ] && [ "$status_code" -le 299 ]; then
        ___x_cmd_cmds_cat "$data_filepath"
        return 0
    fi

    http:error "HttpCode is $status_code, Code is 1"
    return 1
}

____x_cmd_http_request_json_body() (    # Notice: Using subshell
    local ___X_CMD_HTTP_REQUEST_TMP_URL="$1"
    shift

    case "$#" in
        0)                              ___x_cmd_http_request "$___X_CMD_HTTP_REQUEST_TMP_URL" "$(___x_cmd_cmds_cat)"
                return $?;; # Or just pipe
        1)
                if [ "$1" = - ]; then   ___x_cmd_http_request "$___X_CMD_HTTP_REQUEST_TMP_URL" "$(___x_cmd_cmds_cat)"
                else                    ___x_cmd_http_request "$___X_CMD_HTTP_REQUEST_TMP_URL" "$1";
                fi
                return $? ;;
    esac

    local arg; for arg in "$@"; do
        case "$arg" in
            *==*)       shift; ______x_cmd_http_qs_put "${arg%%==*}" "${arg#*==}" ;;  # Query String
            *:*)        shift; ___x_cmd_http_header_put "${arg%%:*}" "${arg#*:}" ;;
            --)         shift;
                        data="$(x jo dict "$@")"
                        break
                        ;;
            -)
                        data="$(___x_cmd_cmds_cat)"       # TODO: Merge the data and the $(x jo $@)
                        ;;
        esac
    done

    ___x_cmd_http_request "$___X_CMD_HTTP_REQUEST_TMP_URL" "$data"
)
