# shellcheck shell=sh
# shellcheck disable=SC2039,3043
# shellcheck disable=SC2046

# Section: Help
_____x_cmd_gl_help__token_setting(){
    printf "\n%s %s \n%s\n" \
        "$(___x_cmd_ui yellow 'Run command to add|repleace token:')" \
        "$(___x_cmd_ui bold cyan "\`x gl --cfg token=<token>\`")"   \
        "$(___x_cmd_ui "$(___x_cmd_gl___get_web_endpoint)/-/profile/personal_access_tokens")"
}

_____x_cmd_gl_help__owner_setting(){
    printf "|\n    %s %s\n    %s %s\n" \
        "$(___x_cmd_ui yellow 'Run current command to setup default owner in the current session:')" \
        "$(___x_cmd_ui bold cyan "\`x gl --cur owner=<owner>\`")" \
        "$(___x_cmd_ui yellow 'Run config  command to save default owner to local configure file:')" \
        "$(___x_cmd_ui bold cyan "\`x gl --cfg owner=<owner>\`")"
}

_____x_cmd_gl_help(){
    x help -m gl "$@" 1>&2
    return 1
}

# EndSection

# Section: HTTP header & body & request
___x_cmd_gl_resp_header(){
   ___x_cmd_cmds_cat "$___X_CMD_GL_TMP/.____x_cmd_gl_curl_header.$$"
}

___x_cmd_gl_resp_code(){
    ___x_cmd_gl_resp_header | _____x_cmd_gx_get_resp_code_by_header
}

___x_cmd_gl_curl(){
    local op="$1"
    local _api_url="$2"
    shift 2
    local ___X_CMD_API_GL_HEADER="-s -H \"Content-Type: application/json\" -D \"$___X_CMD_GL_TMP/.____x_cmd_gl_curl_header.$$\""

    local ___X_CMD_API_GL_TOKEN=""; local _curl_endpoint_tmp="";
   ___x_cmd_gl_cur    ___X_CMD_API_GL_TOKEN:=token  _curl_endpoint_tmp:=endpoint 2>/dev/null
    local ___X_CMD_API_GL_ENDPOINT="${___X_CMD_API_GL_ENDPOINT:-"$_curl_endpoint_tmp"}"

    local ___X_CMD_GL_SHOW_HTTP_CODE=1
    case "$op" in
        get)
            if [ -n "$NO_CACHE" ]; then
                ___x_cmd_api_gl get "$_api_url" $(eval "printf '%s ' $(x curl gencode $(___x_cmd_gl_curl___use_query_data "$@"))")
            else
                x ccmd 10s --        eval "___X_CMD_API_GL_ENDPOINT=$___X_CMD_API_GL_ENDPOINT ___X_CMD_API_GL_TOKEN=$___X_CMD_API_GL_TOKEN ___x_cmd_api_gl get \"$_api_url\" $(eval "printf '%s ' $(x curl gencode $(___x_cmd_gl_curl___use_query_data "$@"))")"
            fi
            ___x_cmd_gl_http_error   eval "___X_CMD_API_GL_ENDPOINT=$___X_CMD_API_GL_ENDPOINT ___X_CMD_API_GL_TOKEN=$___X_CMD_API_GL_TOKEN ___x_cmd_api_gl get \"$_api_url\" $(eval "printf '%s ' $(x curl gencode $(___x_cmd_gl_curl___use_query_data "$@"))")"
            ;;
        post|put|patch|del)
            ___x_cmd_api_gl "$op" "$_api_url" "$(x curl gencode "$@")"
            ___x_cmd_gl_http_error
            ;;
        upload)
            [ -n "$1" ] || M='Please provide upload filepath' arg:ret:64
            local __file_path="$1";  shift;
            [ -f "$__file_path" ] || {
                gl:error "Upload Failure: Not found target file. Please check file exist: $__file_path"
                return 1
            }
            ___X_CMD_API_GL_HEADER="-L -# -D \"$___X_CMD_GL_TMP/.____x_cmd_gl_curl_header\""
            ___x_cmd_api_gl "${___X_CMD_GL_UPLOAD_REQ_METHOD:-"post"}" "$_api_url" --form file=@\""${__file_path}"\" "$(x curl gencode "$@")"
            ___x_cmd_gl_http_error
        ;;
    esac
}

# shellcheck disable=SC2154
___x_cmd_gl_curl___use_query_data(){
    [ $# -gt 0 ] || return
    local name
    printf "%s " "-G"
    for name in "$@";
    do
        if [ "$name" = "p" ];then  [ -z "$p" ] || printf "%s " "path==$p";
        else                                      printf "%s " "$name==" ;
        fi
    done
}

___x_cmd_gl_http_error(){
    if [ "$op" = get ] && [ -n "$___X_CMD_CCMD_AGE" ] && [ "$___X_CMD_CCMD_AGE" -ne -1 ]; then
        gl:debug "Is cache data"
        return 0
    fi
    local http_resp_code=""
    http_resp_code=$(___x_cmd_gl_resp_code)
    if [ -n "$http_resp_code" ] && [ "$http_resp_code" -ge 200 ] && [ "$http_resp_code" -le 303 ]; then
        return 0
    else
        [ $# -eq 0 ] || {
            gl:debug "Cache Clear"
            x ccmd invalidate "$@" 1>/dev/null 2>&1
        }
        [ -z "$___X_CMD_GL_SHOW_HTTP_CODE" ] || {
            gl:error "HTTP Code is $http_resp_code"
            if command -v unset 1>/dev/null; then
                unset ___X_CMD_GL_SHOW_HTTP_CODE
            fi
        }
        return 1
    fi
}

___x_cmd_gl____handle_resp(){
    [ -z "$gl_resp_err" ] || ___x_cmd_gx_printf_error "$gl_resp_err"
    [ -z "$gl_resp_msg" ] || ___x_cmd_gx_printf_error "$gl_resp_msg"
}
# EndSection

# Section: pagination
___x_cmd_gl_get_multi() {
    if [ -n "$page" ] || [ -n "$per_page" ]; then
        ___x_cmd_gl_curl get "$@" page per_page
        return
    fi

    local page=1
    local per_page=100
    local NO_CACHE=1
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gl_get_multi___json_prt "$@"
    else
        ___x_cmd_gl_get_multi___ui_table "$@"
    fi

}

___x_cmd_gl_get_multi___ui_table(){
    ___x_cmd_gl_curl get "$@" page per_page
    printf "\n"
    local next_url
    _____x_cmd_gl_next_url
    [ -n "$next_url" ] || return

    while [ -n "$next_url" ]; do
        ___x_cmd_gl_curl get "$next_url"
        printf "\n"
        _____x_cmd_gl_next_url
    done
}

___x_cmd_gl_get_multi___json_prt(){
    local tmp
    tmp=$(mktemp)
    ___x_cmd_gl_curl get "$@" page per_page > "$tmp"
    printf "\n" >> "$tmp"

    local next_url
    _____x_cmd_gl_next_url
    if [ -z "$next_url" ]; then
        ___x_cmd_cmds_cat "$tmp"
        x rmrf "$tmp"
        return
    fi

    while [ -n "$next_url" ]; do
        ___x_cmd_gl_curl get "$next_url" >> "$tmp"
        printf "\n" >> "$tmp"
        _____x_cmd_gl_next_url
    done
    < "$tmp" x jo q0 \*.\* . | ___x_cmd_gx_merge_multi_page_json_array
    x rmrf "$tmp"
}

_____x_cmd_gl_next_url(){
    next_url="$(command grep "link:" "$___X_CMD_GL_TMP/.____x_cmd_gl_curl_header")"
    next_url="${next_url#*'rel="prev", <'}"
    local tmp_url="${next_url%%'>; rel="next"'*}"
    if [ "$next_url" != "$tmp_url" ];then
        local _split_endpoint=""
        if ! _split_endpoint="$(___x_cmd_gl_cfg get endpoint 2>/dev/null)"; then
            _split_endpoint="https://gitlab.com/api/v4"
        fi
        next_url="${tmp_url#*"$_split_endpoint"}"
    else
        next_url=""
    fi
}
# EndSection

# Section: Parameter Utilities
alias ___x_cmd_gl_param_init_owner_repo='
    local owner_repo=""
    ___x_cmd_gl_param_normalize_repo  || return
'

# shellcheck disable=SC2154,SC2034
___x_cmd_gl_param_normalize_repo(){
    local op="$repo"
    [ -n "$op" ] || op="$1"
    case "$op" in
        .id=*/*)
            gl:error "No support .id=<owner_id>/<repo_name>. Please use .id=<repo_id>"
            return 1
            ;;
        .id=*)
            owner_repo="${op#*'.id='}"
            return 0
            ;;
        */*)
            owner_repo="$op"
            ;;
        "")
            local owner=""; local repo="";
           ___x_cmd_gl_cur owner:=owner repo:=repo 2>/dev/null
            case "$repo" in
                */*) owner_repo="$repo"     ;;
                "")  owner_repo="$(___x_cmd_gx_get_owner_repo)" ;;
                *)
                    if [ -n "$owner" ]; then
                        owner_repo="${owner}/${repo}"
                    else
                        gl:error -h "$(_____x_cmd_gl_help__owner_setting)" "No owner provided. Default owner not set."
                        return 1
                    fi
                ;;
            esac
            ;;
        *)
            local x_="";___x_cmd_gl_cur get_ owner 2>/dev/null
            if [ -z "$x_" ]; then
                gl:error -h "$(_____x_cmd_gl_help__owner_setting)" "No owner provided. Default owner not set."
                return 1
            fi
            owner_repo="${x_}/${op}"
            ;;
    esac
    owner_repo="$(printf "%s" "$owner_repo" | ___x_cmd_gl___url_path_encode)"
}

# EndSection

# Section: gl utils
___x_cmd_gl____transform_member_access(){
    case $access_level in
        owner)          access_level=50 ;;
        maintainer)     access_level=40 ;;
        developer)      access_level=30 ;;
        reporter)       access_level=20 ;;
        guest)          access_level=10 ;;
    esac
}

# shellcheck disable=2016
___x_cmd_gl___url_encode(){
    [ -n "$1" ] || M='accepts 1 arg(target str), received empty' arg:ret:64
    printf "%s\n" "$1" |  x cawk  \
        -f "$___X_CMD_ROOT_MOD/awk/lib/url.awk" \
        -f "$___X_CMD_ROOT_MOD/awk/lib/sh.awk"  \
        '{ print urlencode( $0 ) }'
}

___x_cmd_gl___url_path_encode(){
    sed s:'/':'%2F':g
}

# NOTE: remove prefix: _host_tmp="${_host_tmp#*'://'}";
___x_cmd_gl___get_web_endpoint(){
    local _endpoint_tmp=""
    if _endpoint_tmp="$(___x_cmd_gl_cfg get endpoint 2>/dev/null)"; then
        printf "%s" "${_endpoint_tmp%'/api/'*}"
    else
        printf "%s" "https://gitlab.com"
    fi
}

___x_cmd_gl___get_owner_(){
   ___x_cmd_gl_cur get_ owner || x jo env . x_=.username <<A
        $(___x_cmd_gl_curl get "/user")
A
}

# NOTE: need unset json ENFORCE_JSON. the util func only using on subshell
___x_cmd_gl_owner_type_query() {
    param:void
    local owner="$1";   arg:init gl;
    [ -n "$owner" ]  || M='Please privide owner name' arg:ret:64
    [ "${owner##*/}" = "${owner}" ] || { printf "%s" "repo"; return 0; }
    unset json ENFORCE_JSON
    local types=""
    for types in "org" "user"
    do
        if  ___x_cmd_gl_${types}_info "$owner" 1>/dev/null 2>&1;then
            printf "%s" "$types"
            return
        fi
    done
    return 1
}
# EndSection
