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

xrc:mod:lib gt repo/util  repo/apply  repo/branch  repo/commit  repo/hook  repo/collaborator  repo/page  repo/push  repo/tag \
    repo/pr/index  repo/pr/assign  repo/pr/tester  repo/release/index

___x_cmd_gt_repo(){
    param:scope         ___x_cmd_gt
    param:subcmd ___x_cmd_gt_repo       \
        "browse|b"      "Open Gitee repo in the web browser"            \
        ls              "Interactive UI show repo by owner"             \
        ll              "List repo by owner"                            \
        create          "Create repo"                                   \
        "edit|ed"       "Edit repo configure"                           \
        rename          "Rename repo"                                   \
        info            "Show detailed information by repo"             \
        rm              "Remove repo"                                   \
        clear           "Clear repo"                                    \
        apply           "Manage repo by declare configure"              \
        "cl|clone"      "Clone repo from gitee"                         \
        fork            "Fork repo from gitee"                          \
        commit          "repo commit management"                        \
        collaborator    "repo collaborator management"                  \
        branch          "repo branch management"                        \
        pr              "repo pull request management"                  \
        issue           "repo issue management"                         \
        hook            "repo webhooks management"                      \
        tag             "repo tag management"                           \
        release         "repo release management"                       \
        push            "repo push rule management"                     \
        page            "repo page management"
    param:subcmd:try
    param:run

    ___x_cmd_gt_repo_ls
}

# Section: Create
___x_cmd_gt_repo_create(){
    param:scope     ___x_cmd_gt
    param:dsl       '
option:
    #1                      "<owner_path>/<repo_path>"              <>:RepoPath

    --access                "private,public"                        <>="private"
    -p|--path               "repo path"                             <>=""
    --description           "description"                           <desc>=""
    --homepage              "homepage"                              <>=""
    --gitignore_template    "git ignore template"                   <>:Ignore=""
    --license_template      "use license template"                  <>:License=""
    --no_issue              "Ban repo issue"
    --no_wiki               "Ban repo wiki"
    --no_comment            "Ban repo comment"
    --auto_init             "Auto init repo"
    --json|-j               "Output origin json data"
'
    param:run
    [ "$#" -ne 0 ] || M='accepts 1 arg(s) (<ownerPath>/<RepoPath>), received empty' arg:ret:64

    local name=""
    for name in "$@"; do
        local owner_type=user
        [ "${name%%/*}" = "$name" ] || {
            if ! owner_type="$(___x_cmd_gt_owner_type_query "${name%%/*}")"; then
                gt:error "No found any onwer type. Please check owner exist ${name%%/*}"
                return 1
            fi
        }

        "___x_cmd_gt_${owner_type}_repo_create" ${p:+"-p"} ${p:+"$p"} \
            ${homepage:+"--homepage"} ${homepage:+"$homepage"} ${description:+"--description"} ${description:+"$description"}  \
            ${no_issue:+"--no_issue"} ${no_wiki:+"--no_wiki"}  ${no_comment:+"--no_comment"}   ${auto_init:+"--auto_init"}     \
            ${gitignore_template:+"--gitignore_template"}      ${gitignore_template:+"$gitignore_template"}                    \
            ${license_template:+"--license_template"}          ${license_template:+"$license_template"}                        \
            ${access:+"--access"} ${access:+"$access"} "$name"
    done
}

# shellcheck disable=SC2154
# https://gitee.com/api/v5/swagger#/postV5UserRepos
___x_cmd_gt_user_repo_create(){
    param:scope     ___x_cmd_gt
    param:dsl       '
option:
    #1                      "repo names"                    <>:RepoName

    -p|--path               "repo path"                     <>=""
    --access                "private,public"                <>:RepoAccess=private
    --description           "description"                   <>=""
    --homepage              "homepage"                      <>=""
    --gitignore_template    "Git Ignore"                    <>:Ignore=""
    --license_template      "use license template"          <>:License=""
    --no_issue              "Ban repo issue"
    --no_wiki               "Ban repo wiki"
    --no_comment            "Ban repo comment"
    --auto_init             "auto init repo"
    --json|-j               "output origin json data"
'
    param:run
    [ "$#" -ne 0 ] || M='accepts 1 arg(s) (repo name), received empty' arg:ret:64

    local private=""
    case "$access" in
        public)     private=false   ;;
        private)    private=true    ;;
    esac

    local name="${___X_CMD_TX}"
    local gen_gt_json=""
    gen_gt_json="$(
        param:option2json +name +private "${p:+"path=p"}" -access -p -auto_init -json \
            'has_issues=^no_issue'        'has_wiki=^no_wiki' \
            'can_comment=^no_comment'     'auto_init=^^auto_init')"
    gt:debug "$gen_gt_json"

    for name in "$@"; do
        x tmpl "$gen_gt_json" "${name##%/}" | \
            ___x_cmd_gt_curl post "/user/repos" "@-" | \
            ___x_cmd_gt_repo____ui_handler Creating
    done
}


# https://gitee.com/api/v5/swagger#/postV5EnterprisesEnterpriseRepos
# shellcheck disable=SC2154,SC2034
___x_cmd_gt_enterprise_repo_create(){
    param:scope     ___x_cmd_gt
    param:dsl       '
type:
    Access  =   private public innerSource
option:
    #1                      "repo names"                        <>:RepoPath

    --enterprise|-e         "enterprise space address"          <>:EnterpriseSpaceName=""
    -p|--path               "repo path"                         <>=""
    --access                "private,public,innerSource"        <>:Access=private
    --description           "description"                       <>=""
    --homepage              "homepage"                          <>=""
    --gitignore_template    "Git Ignore"                        <>:Ignore=""
    --license_template      "license"                           <>:License=""
    --no_issue              "Ban repo issue"
    --no_wiki               "Ban repo wiki"
    --no_comment            "Ban repo comment"
    --auto_init             "auto init repo"

    --outsourced            "repo outsourced"
    --project_creator       "Provide project_creator"           <>=""
    --members               "Provide members(name or email)"    <>=""
    --json|-j               "output origin json data"
'
    param:run
    [ "$#" -ne 0 ] || M='accepts 1 arg(s) (<ownerPath>/<RepoPath>), received empty' arg:ret:64

    local name=""
    [ -n "$enterprise" ] || {
        for name in "$@"; do
            case "$name" in
                */*)    ;;
                *)      gt:error "Please provide --enterprise or add enterprise prefix before reponame"
                        return 1
            esac
        done
    }

    case "$access" in
        private)        private=0 ;;
        public)         private=1 ;;
        innerSource)    private=2 ;;
    esac
    name="${___X_CMD_TX}"
    local gen_gt_json=""
    gen_gt_json="$(
        param:option2json +name +private "${p:+"path=p"}" -access -p \
        'has_issues=^no_issue'            'has_wiki=^no_wiki'              'outsourced=^^outsourced' \
        'can_comment=^no_comment'         'auto_init=^^auto_init')"
    gt:debug "$gen_gt_json"

    for name in "$@"; do
        local this_ent="${name%%/*}"
        [ "$this_ent" != "$name" ] || this_ent="$enterprise"
        x tmpl "$gen_gt_json" "${name##*/}" | \
            ___x_cmd_gt_curl post "/enterprises/${this_ent}/repos" "@-" | \
            ___x_cmd_gt_repo____ui_handler Creating
    done
    return 0
}
# EndSection

# Section: App
# shellcheck disable=SC2154,SC2145,SC2120
___x_cmd_gt_repo_ls(){
    if ___x_cmd_gx_has_format_args "$@"; then
        ___x_cmd_gt_repo_ll "$@"
        return
    fi

    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "owner path"        <owner_path>=""
    --page          "page"              <>="1"
    --per_page      "per_page"          <>="20"
'
    param:run

    local owner_type=user
    [ -z "$1" ] || {
        if ! owner_type="$(___x_cmd_gt_owner_type_query "$1")"; then
            gt:error "No found any onwer type. Please check owner exist $1"
            return 1
        fi
    }

    "___x_cmd_gt_${owner_type}_repo_ls" --page "$page" --per_page "$per_page" "$1"
}
# EndSection

# Section: List
# shellcheck disable=SC2154,SC2145
___x_cmd_gt_repo_ll(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "owner path"                                    <owner_path>=""
    --page          "page"                                          <>="1"
    --per_page      "per_page"                                      <>="30"

    --json|-j       "output origin json data"
    --csv           "output csv data"
    --yml           "output yml data"
'
    param:run

    local owner_type=user
    [ -z "$1" ] || {
        if ! owner_type="$(___x_cmd_gt_owner_type_query "${1%%/*}")"; then
            gt:error "No found any onwer type. Please check owner exist $1"
            return 1
        fi
    }
    "___x_cmd_gt_${owner_type}_repo_ll" --page "$page" --per_page "$per_page" ${json:+"--json"} ${csv:+"--csv"} ${yml:+"--yml"} "${1%%/*}"
}
# EndSection

# Section: Edit

# shellcheck disable=SC2154,SC2034
# https://gitee.com/api/v5/swagger#/patchV5ReposOwnerRepo
___x_cmd_gt_repo_edit(){
    param:scope     ___x_cmd_gt
    param:dsl       '
type:
    Access  =   private public ""
options:
    #1                      "<owner_path>/<repo_path>"                                              <>:RepoPath
    --name                  "rename repo(default:the repo path)"                                    <>=""

    --access                "private,public"                                                        <>:Access=""
    -p|--path               "repo path"                                                             <>=""
    --description           "repo description"                                                      <>=""
    --homepage              "homepage"                                                              <>=""
    --default_branch        "repo default branch"                                                   <>=""
    --default_merge_method  "repo default merge pr way"                                             <>="" = merge squash rebase ""
    --no_issue              "Ban repo issue"
    --no_wiki               "Ban repo wiki"
    --no_comment            "Ban repo comment"
    --no_pull_requests      "Ban repo pull request"
    --no_online_edit        "Ban repo online edit"
    --no_lightweight_pr     "Ban repo lightweight pr"
    --no_security_hole      "Ban repo issue public access"
    --json|-j               "output origin json data"
    --yes|-y                "Ignore access private prompt interception"
'
    param:run
    local repo="$1"
    local private=""
    case "$access" in
        public)     private=false ;;
        private)    private=true
            [ "$yes" = "true" ] || ___x_cmd_ui_yesno "Are you sure to edit repository access to $(___x_cmd_ui bold red "$access") ?${___X_CMD_UNSEENCHAR_NEWLINE}  - Will only authorized users will have access${___X_CMD_UNSEENCHAR_NEWLINE}  - Loss of all stars and watchers${___X_CMD_UNSEENCHAR_NEWLINE}" || return 1
        ;;
    esac
    [ -n "$name" ] || name="${repo##*/}"
    local gen_gt_json=""
    gen_gt_json="$(
        param:option2json +repo ${access:+"+private"} "${p:+"path=p"}" -access -p -yes \
            'has_issues=^no_issue'                        'has_wiki=^no_wiki' \
            'can_comment=^no_comment'                     'security_hole_enabled=^no_security_hole' \
            'pull_requests_enabled=^no_pull_requests'     'lightweight_pr_enabled=^no_lightweight_pr'  \
            'no_online_edit=^no_online_edit')"
    gt:debug "$gen_gt_json"

    ___x_cmd_gt_param_init_owner_repo
    ___x_cmd_gt_curl patch "/repos/${owner_repo}" "gen_gt_json" | \
        ___x_cmd_gt_repo____ui_handler Modify
}
# EndSection

# Section: Rename
___x_cmd_gt_repo_rename(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "Repo Rename"                   <>
    --repo|-r       "<owner_path>/<repo_path>"      <>:RepoPath
    --json|-j       "output origin json data"
    --yes|-y        "Ignore rename prompt interception"
'
    param:run
    ___x_cmd_gt_param_init_owner_repo
    local name="${1##*/}"
    local p="$name"
    [ "$yes" = "true" ] || ___x_cmd_ui_yesno "Are you sure to rename repository $(___x_cmd_ui bold red "$owner_repo => ${owner_repo%/*}/${name}") ?" || return 1

    local gen_gt_json=
    gen_gt_json="$(param:option2json -repo -json -yes +name path=p)"
    gt:debug "$gen_gt_json"

    ___x_cmd_gt_curl patch "/repos/${owner_repo}" "gen_gt_json" | ___x_cmd_gt_repo____ui_handler Modify
}
# EndSection

# Section: Info
# shellcheck disable=SC2154
# https://gitee.com/api/v5/swagger#/getV5ReposOwnerRepo
___x_cmd_gt_repo_info(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "<owner_path>/<repo_path>"      <>:RepoPath
    --json|-j       "output origin json data"
'
    param:run
    local repo="$1"
    ___x_cmd_gt_param_init_owner_repo

    ___x_cmd_gt_curl get "/repos/${owner_repo}" | ___x_cmd_gt_repo____ui_handler Info
}
# EndSection

# Section: Remove & Clear
# https://gitee.com/api/v5/swagger#/deleteV5ReposOwnerRepo
# shellcheck disable=SC2181,SC2154,SC2034
___x_cmd_gt_repo_rm(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1          "Provide repo path list"                <>
    --yes|-y    "Ignore remove prompt interception"
'
    param:run
    [ "$#" -ne 0 ] || M='accepts 1 arg(s) (ownerPath/RepoPath), received empty' arg:ret:64

    local owner_repo=""
    local i=""
    for i in "$@"; do
        ___x_cmd_gt_param_normalize_repo "$i"
        [ "$yes" = "true" ] || ___x_cmd_ui_yesno "Are you sure to remove repo: $(___x_cmd_ui bold red "$owner_repo") ?" || continue
        ___x_cmd_gt_curl del "/repos/$owner_repo" | (
                [ -z "$___X_CMD_GT_IN_TEST" ] || { ___x_cmd_cmds_cat; return; }
                x jo env . gt_resp_err=.message gt_resp_err=.error
                if ___x_cmd_gt_http_error; then
                    ___x_cmd_ui_tf true  "[Success]: Remove repo $owner_repo"
                else
                    ___x_cmd_ui_tf false "Remove repo $owner_repo failure:" >&2
                    ___x_cmd_gt____handle_resp
                fi
            )
    done
}

# shellcheck disable=SC2181,SC2034
# https://gitee.com/api/v5/swagger#/putV5ReposOwnerRepoClear
___x_cmd_gt_repo_clear(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1          "<owner_path>/<repo_path>"              <>:RepoPath
    --yes|-y    "Ignore remove prompt interception"
'
    param:run
    [ -n "$1" ] || M='accepts 1 arg(ownerPath/RepoPath), received empty' arg:ret:64
    local repo="$1"
    ___x_cmd_gt_param_init_owner_repo
    [ "$yes" = "true" ] || ___x_cmd_ui_yesno "Are you sure to remove repo: $(___x_cmd_ui bold red "$owner_repo") ?" || return 1
    ___x_cmd_gt_curl put "/repos/${owner_repo}/clear" | (
            [ -z "$___X_CMD_GT_IN_TEST" ] || { ___x_cmd_cmds_cat; return; }
            x jo env . gt_resp_err=.message gt_resp_err=.error
            if ___x_cmd_gt_http_error; then
                ___x_cmd_ui_tf true  "[Success]: Clearing repo $owner_repo"
            else
                ___x_cmd_ui_tf false "Clearing repo $owner_repo failure:" >&2
                ___x_cmd_gt____handle_resp
                return 1
            fi
        )
}
# EndSection

# Section: Browse
___x_cmd_gt_repo_browse(){
    param:scope ___x_cmd_gt
    param:dsl <<A
options:
    #1           "<owner_path>/<repo_path>"      <>:RepoPath=""
A
    param:run
    local repo="$1"
    ___x_cmd_gt_param_init_owner_repo
    [ -n "$owner_repo" ] || M='accepts 1 arg (<owner>/<repo>), received empty' arg:ret:64
    x open "https://gitee.com/${owner_repo}"
}
# EndSection

# Section: repo UI
___x_cmd_gt_repo____ui_handler(){
    if [ -n "$ENFORCE_JSON" ] || [ -n "$json" ]; then
        ___x_cmd_cmds_cat
        ___x_cmd_gt_http_error
        return
    fi
    (
        case "$1" in
            Creating|Modify)
                x jo env . _url=.html_url gt_resp_err=.message gt_resp_err=.error \
                    full_name=.full_name
                _inf_msg="$1 $name successfully"
                _err_msg="$1 $name failure"
            ;;
            Info)
                x jo env . _url=.html_url gt_resp_err=.message gt_resp_err=.error \
                    full_name=.full_name name=.name
                _inf_msg="$owner_repo information"
                _err_msg="No find any information data by $owner_repo"
            ;;
        esac
        if [ -n "$_url" ]; then
            ___x_cmd_ui_tf  true "${_inf_msg}:" ${full_name:+"Path: $full_name"} ${name:+"Name: $name"} ${_url:+"URL: $_url"}
        else
            ___x_cmd_ui_tf false "${_err_msg}:" >&2
            ___x_cmd_gt____handle_resp
            return 1
        fi
    )
}
# EndSection
