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

___x_cmd_gl_group(){
    param:scope     ___x_cmd_gl
    param:subcmd ___x_cmd_gl_group              \
        ls         "List all groups"            \
        info       "Show group information"     \
        create     "Create group"               \
        "edit|ed"  "Update group"               \
        rm         "Remove group"               \
        member     "group member management"    \
        repo       "group repo management"      \
        mr         "List group merge request"   \
        variable   "Group varibale manage"
    param:subcmd:try
    param:run

    ___x_cmd_gl_group _param_help_doc
    return 1
}

# Section: List
# https://docs.gitlab.com/ee/api/groups.html#list-groups
___x_cmd_gl_group_ls(){
    param:scope     ___x_cmd_gl
    param:dsl       '
type:
    order_by = name path id  similarity
    Sort = asc desc
options:
    --sort                      "Order groups in asc or desc order."                                <>:Sort="asc"  = asc desc
    --search                    "Return the list of authorized groups matching the search criteria" <>=""
    --order_by                  "Order groups by"                                                   <>="name"   = name path id similarity
    --skip_groups               "Skip the group IDs passed"                                         <>=""
    --min_access_level          "Limit to groups where current user has at least this access level" <>:Number=""
    --owned                     "Limit to groups explicitly owned by the current user"
    --statistics                "Include group statistics"
    --all_available             "Show all the groups you have access to"
    --top_level_only            "Limit to top level groups, excluding all subgroups"
    --with_custom_attributes    "Include custom attributes in response"

    --per_page                  "Results per page (max 100)"                                        <>=""
    --page                      "Page number of the results to fetch."                              <>=""
    --json|-j                   "output raw JSON data"
'
    param:run
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gl_get_multi "/groups" sort search order_by skip_groups min_access_level owned statistics all_available top_level_only with_custom_attributes
    else
        ___x_cmd_gl_get_multi "/groups" sort search order_by skip_groups min_access_level owned statistics all_available top_level_only with_custom_attributes | \
            x jo 2c             .id .name .path .visibility .web_url | \
            x csv header --add   ID  Name  Path  Visibility  URL     | \
            x csv static_tab
    fi
}
# EndSection

# Section: Info
# https://docs.gitlab.com/ee/api/group_boards.html#list-all-group-issue-boards-in-a-group
___x_cmd_gl_group_info(){
    param:scope     ___x_cmd_gl
    param:dsl       '
options:
    #1                          "<group_path> or .id=<group_id>"                                       <>
    --with_projects             "Include details from projects that belong to the specified group"
    --with_custom_attributes    "Include custom attributes in response"

    --json|-j                   "output raw JSON data"
'
    param:run
    [ -n "$1" ] || M='accepts arg (<group_path> or .id=<group_id>), received empty' arg:ret:64
    local _avt_group="$1"
    ___x_cmd_gl____transform_avt_group || return
    ___x_cmd_gl_curl get "/groups/$_avt_group" | _____x_cmd_group_ui_utils Info
}
# EndSection

# Section: Create
# shellcheck disable=SC2181,SC2034
# TODO:On gitlab SaaS, you must use the gitlab UI to create groups without a parent group. You cannot use the API to do this.???
# https://docs.gitlab.com/ee/api/groups.html#new-group
___x_cmd_gl_group_create(){
    param:scope     ___x_cmd_gl
    param:dsl       '
options:
    #1                          "The name of the group."        <>
    -p|--path                   "The path of the group."        <>=""
    --description               "The group description."        <>=""
    --visibility                "The groups visibility."        <>="" = "" private internal public
    --subgroup_creation_level   "Allowed to create subgroups."  <>="" = "" maintainer owner
    --json|-j                   "output raw JSON data"
'
    param:run
    [ -n "$1" ] || M='accepts 1 arg(group name), received empty' arg:ret:64
    local name="$1"
    [ -n "$p" ] || p="$name"
    local gen_gl_json
    gen_gl_json="$(param:option2json -p +name path=p)"
    gl:debug "$gen_gl_json"

    ___x_cmd_gl_curl post "/groups" "gen_gl_json" | _____x_cmd_group_ui_utils Creating
}
# EndSection

# Section: Edit
# https://docs.gitlab.com/ee/api/groups.html#update-group
___x_cmd_gl_group_edit(){
    param:scope     ___x_cmd_gl
    param:dsl       '
options:
    #1                          "<group_path> or .id=<group_id>"   <>
    -p|--path                   "The path of the group"            <>=""
    --name                      "The name of the group"            <>=""
    --description               "The group description."           <>=""
    --visibility                "The groups visibility."           <>="" = "" private internal public
    --subgroup_creation_level   "Allowed to create subgroups."     <>="" = "" maintainer owner

    --json|-j                   "output raw JSON data"
'
    param:run
    [ -n "$1" ] || M='accepts arg (<group_path> or .id=<group_id>), received empty' arg:ret:64
    local _avt_group="$1"
    ___x_cmd_gl____transform_avt_group || return

    local gen_gl_json
    gen_gl_json="$(param:option2json -p ${p:+"path=p"})"
    gl:debug "$gen_gl_json"

    ___x_cmd_gl_curl put "/groups/$_avt_group" "gen_gl_json" | _____x_cmd_group_ui_utils Update
}
# EndSection

# Section: Remove
# https://docs.gitlab.com/ee/api/groups.html#remove-group
# shellcheck disable=2154
___x_cmd_gl_group_rm(){
    param:scope     ___x_cmd_gl
    param:dsl       '
options:
    #1                       "<group_path> or .id=<group_id>"                                      <>
    --yes|-y                 "Ignore remove prompt interception"
'
    param:run
    [ "$#" -ne 0 ] || M='accepts arg(s) (<group_path> or .id=<group_id>), received empty' arg:ret:64

    local _avt_group=""
    for _avt_group in "$@"; do
        ___x_cmd_gl____transform_avt_group || return
        [ "$yes" = "true" ] || ___x_cmd_ui_yesno "Are you sure groups to remove: $(___x_cmd_ui bold red "$_avt_group") ?" || continue
        ___x_cmd_gl_curl del "/groups/$_avt_group" | (
            x jo env . gl_resp_err=.error gl_resp_msg=.message
            if ___x_cmd_gl_http_error; then
                ___x_cmd_ui_tf  true "[Success]: Remove groups $_avt_group"
            else
                ___x_cmd_ui_tf false "Remove groups $_avt_group failure:"
                ___x_cmd_gl____handle_resp
                return 1
            fi
        )
    done
}
# EndSection

# Section: Group Merge Request List
# https://docs.gitlab.com/ee/api/merge_requests.html#list-group-merge-requests
___x_cmd_gl_group_mr(){
    param:scope     ___x_cmd_gl
    param:dsl       '
options:
    --id                          "The ID or URL-encoded path of the repo owned by the authenticated user"                                                                                       <>
    --assignee_id                 "Returns merge requests assigned to the given user id."                                                                                                        <>:Number=""
    --author_id                   "Return prs created by the given user id."                                                                                                                     <>:Number=""
    --author_username             "Return prs created by the given username."                                                                                                                    <>=""
    --approved_by_ids             "Returns merge requests which have been approved by all the users with the given id, with a maximum of 5. "                                                    <>:array=""
    --approver_ids                "Returns merge requests which have specified all the users with the given id as individual approvers."                                                         <>:array=""
    --approved_by_usernames       "Returns merge requests which have been approved by all the users with the given username, with a maximum of 5."                                               <>=""
    --created_after               "Return merge requests created on or after the given time. Expected in ISO 8601 format."                                                                       <>:datetime=""
    --created_before              "Return merge requests created on or before the given time."                                                                                                   <>:datetime=""
    --labels                      "Return merge requests matching a comma-separated list of labels."                                                                                             <>=""
    --milestone                   "Return merge requests for a specific milestone. "                                                                                                             <>=""
    --my_reaction_emoji           "Return merge requests reacted by the authenticated user by the given emoji. "                                                                                 <>=""
    --not                         "Return merge requests that do not match the parameters supplied. "                                                                                            <>:hash=""
    --non_archived                "Return merge requests from non archived projects only. Default is true."
    --order_by                    "Return requests ordered by created_at, title, or updated_at fields. Default is created_at. "                                                                  <>=""
    --reviewer_id                 "Returns merge requests which have the user as a reviewer with the given user id.  "                                                                           <>=""
    --reviewer_username           "Returns merge requests which have the user as a reviewer with the given username. "                                                                           <>=""
    --scope                       "Return merge requests for the given scope. Defaults to created_by_me."                                                                                        <>=""
    --search                      "Search merge requests against their title and description."                                                                                                   <>=""
    --sort                        "Return requests sorted in asc or desc order. Default is desc."                                                                                                <>=""
    --state                       "Return all merge requests or just those that are opened, closed, locked, or merged."                                                                          <>=""
    --source_branch               "Return merge requests with the given source branch."                                                                                                          <>=""
    --target_branch               "Return merge requests with the given target branch."                                                                                                          <>=""
    --updated_after               "Return prs updated on or after the given time."                                                                                                               <>:datetime=""
    --updated_before              "Return prs updated on or before the given time."                                                                                                              <>:datetime=""
    --view                        "If simple, returns the iid, URL, title, description, and basic state of merge request."                                                                       <>=""
    --with_labels_details         "If true, the response returns more details for each label in labels field: :name, :color, :description, :description_html,:text_color.Default is false."      <>:bool="false"  = true false
    --with_merge_status_recheck   "If true, this projection requests (but does not guarantee) that the merge_status field be recalculated asynchronously"                                        <>:bool="false"  = true false
    --json|-j                     "output raw JSON data"
'
    param:run

    [ -n "$group" ] || M='accepts option --group (<group_path> or .id=<group_id>), received empty' arg:ret:64
    local _avt_group="$group"
    ___x_cmd_gl____transform_avt_group || return
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gl_get_multi "/groups/${_avt_group}/merge_requests" sort order_by search state labels source_branch target_branch
    else
        ___x_cmd_gl_get_multi "/groups/${_avt_group}/merge_requests" sort order_by search state labels source_branch target_branch | \
            x jo 2c             .id .iid .project_id .title .state .web_url | \
            x csv header --add   ID  IID  Project_Id  Title  State  Url     | \
            x csv static_tab
    fi
}

# EndSection

___x_cmd_gl_subgroup(){
    param:scope     ___x_cmd_gl
    param:subcmd ___x_cmd_gl_subgroup   \
        ls          "List all subgroups"    \
        create      "Create subgroups"
    param:subcmd:try
    param:run

    ___x_cmd_gl_subgroup _param_help_doc
    return 1
}

# Section: List
# https://docs.gitlab.com/ee/api/groups.html#list-a-groups-subgroups
___x_cmd_gl_subgroup_ls(){
    param:scope     ___x_cmd_gl
    param:dsl       '
type:
    order_by = name path id  similarity
    sort = asc desc
options:
    #1                          "The ID or URL-encoded path of the group of the immediate parent group" <>
    --sort                      "Order groups in asc or desc order."                                    <>=""
    --search                    "Return the list of authorized groups matching the search criteria"     <>=""
    --order_by                  "Order groups by name, path, or id"                                     <>=""
    --skip_groups               "Skip the group IDs passed"                                             <>=""
    --min_access_level          "Limit to groups where current user has at least this role"             <>:Number=""
    --owned                     "Limit to groups explicitly owned by the current user"
    --statistics                "Include group statistics (administrators only)"
    --all_available             "Show all the groups you have access to"
    --with_custom_attributes    "Include custom attributes in response (administrators only)"

    --json|-j                   "output raw JSON data"
'
    param:run

    [ -n "$1" ] || M='accepts arg (<group_id> or /<group_path>), received empty' arg:ret:64
    local _avt_group="$1"
    ___x_cmd_gl____transform_avt_group || return

    if [ -n "$json" ]  || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gl_curl get "/groups/$_avt_group/subgroups" sort search order_by skip_groups min_access_level owned statistics all_available with_custom_attributes
    else
        ___x_cmd_gl_curl get "/groups/$_avt_group/subgroups" sort search order_by skip_groups min_access_level owned statistics all_available with_custom_attributes | \
            x jo 2c             .id .name .path .visibility .web_url | \
            x csv header --add   ID  Name  Path  Visibility  URL     | \
            x csv static_tab
    fi
}
# EndSection

# Section: Create
# https://docs.gitlab.com/ee/api/groups.html#new-subgroup
___x_cmd_gl_subgroup_create(){
    param:scope     ___x_cmd_gl
    param:dsl       '
options:
    #1                  "subgroup name"                                 <>
    --parent            "<parent_group_path> or .id=<parent_group_id>"  <>
    -p|--path           "subgroup path (default subgroup name)"         <>=""
    --json|-j           "output raw JSON data"
'
    param:run
    [ -n "$1" ] || M='accepts arg (new subgroup name), received empty' arg:ret:64
    local name="$1"

    [ -n "$parent" ] || M='accepts option (--parent <parent_group_path> or .id=<parent_group_id>), received empty' arg:ret:64
    local _avt_group="$parent"
    ___x_cmd_gl____transform_avt_group || return

    [ -n "$p" ] || p="$name"

    gen_gl_json="$(param:option2json -p -parent   +name parent_id=_avt_group path=p)"
    gl:debug "$gen_gl_json"
    ___x_cmd_gl_curl post "/groups" "gen_gl_json"| _____x_cmd_group_ui_utils Creating
}
# EndSection

# Section: UI util
_____x_cmd_group_ui_utils(){
    if  [ -n "$ENFORCE_JSON" ] || [ -n "$json" ]; then
        ___x_cmd_cmds_cat
        ___x_cmd_gl_http_error
        return
    fi
    (
        local _id=""
        case "$1" in
            Info)
                x jo env . _id=.id gl_resp_err=.error gl_resp_msg=.message \
                    name=.name dir=.path visibility=.visibility url=.web_url
                _inf_msg="Getting groups info successfully"
                _err_msg="Getting groups info failure"
                ;;
            Creating|Update)
                x jo env . _id=.id gl_resp_err=.error gl_resp_msg=.message \
                    name=.name dir=.path url=.web_url visibility=.visibility
                _inf_msg="$1 group $name successfully"
                _err_msg="$1 group $name failure"
                ;;
        esac
        if [ -n "$_id" ]; then
            ___x_cmd_ui_tf  true "${_inf_msg}:" "Id: $_id" ${name:+"Name: $name"} ${dir:+"Path: $dir"} ${url:+"Url: $url"} ${visibility:+"Visibility: $visibility"}
        else
            ___x_cmd_ui_tf false "${_err_msg}:"
            ___x_cmd_gl____handle_resp
            return 1
        fi
    )
}
# EndSection
