# shellcheck    shell=dash disable=SC2034    # xrc

# ___x_cmd_pkg_remove --sphere <sphere name> --sphereroot <sphere root path> --osarch <osarch> <pkg> <version>
# ___x_cmd_pkg_sphere_remove(){
#     pkg:trace pkg/remove
#     pkg:sphere:parse:args
#     pkg:debug \
#         --sphere "$sphere_name" --sphereroot "$___X_CMD_PKG_ROOT_SPHERE" \
#         --name "$name" --version "$version" --osarch "$osarch" remove

#     pkg:info "Removing $name $version"

#     x fslock run "pkg_sphere_${sphere_name}_${name}_${version}_${osarch}" \
#         ___x_cmd_pkg_sphere_gc_remove___populate "$name" "$version" "$osarch" || return $?

#     x fslock run "pkg_${name}_${version}_${osarch}" \
#         ___x_cmd_pkg_sphere_gc_remove___ball "$name" "$version" "$osarch" || return $?

# }
___x_cmd_pkg_sphere_gc_remove(){
    local op="$1"
    case "$op" in
        populate|ball|main|silent)
            shift; ___x_cmd_pkg_sphere_gc_remove___"$op" "$@" ;;
        *)  ___x_cmd_pkg_sphere_gc_remove___main "$@" ;;
    esac
}

___x_cmd_pkg_sphere_gc_remove___populate(){
    pkg:sphere:parse:args

    local x_treename=; ___x_cmd_pkg_treename_ "$name" "$version" "$osarch" || return $?
    local tgt="$___X_CMD_PKG_ROOT_SPHERE/$sphere_name/$x_treename/$name/$version"
    [ -d "$tgt" ] || {
        x_treename=
        for tgt in "$___X_CMD_PKG_ROOT_SPHERE/$sphere_name/"*"/$name/$version"; do
            [ -d "$tgt" ] || continue
            x_treename="${tgt#"$___X_CMD_PKG_ROOT_SPHERE/$sphere_name/"}"
            x_treename="${x_treename%%"/$name/$version"}"
            pkg:debug "Attempting to remove pkg [name=$name] [version=$version] under [x_treename=$x_treename]"
            break
        done
    }

    pkg:debug "Attempting to remove $x_treename $name $version"
    ___x_cmd_pkg_sphere_depend file rm      --sphere "$sphere_name" --sphereroot "$___X_CMD_PKG_ROOT_SPHERE" --osarch "$osarch" "$name" "$version" || return $?
    if ! [ -d "$tgt" ];then
        pkg:warn "Not found the path of pkg [name=$name] [version=$version] folder"
        return 1
    else
        ___x_cmd_cmds chmod -R 700 "$tgt" >/dev/null 2>&1
        ___x_cmd_pkg_sphere_xbin remove_cache   --sphere "$sphere_name" --sphereroot "$___X_CMD_PKG_ROOT_SPHERE" --osarch "$osarch" "$name" "$version" || return $?
        # x:warn x rmrf "$tgt"
        ___x_cmd rmrf "$tgt"

        # ___x_cmd_pkg_sphere_depend remove       --sphere "$sphere_name" --sphereroot "$___X_CMD_PKG_ROOT_SPHERE" --osarch "$osarch" "$name" "$version" || return $?

        local tgt_folder=${tgt%/*}
        [ ! -d "$tgt_folder" ] || ! ___x_cmd fsiter --dirempty --folder "$tgt_folder" || ___x_cmd rmrf "$tgt_folder"
        pkg:info "Successfully removed $x_treename $name $version"
    fi
}

___x_cmd_pkg_sphere_gc_remove___ball(){
    local name="$1";        [ -n "$name" ]      || N=pkg M="Provide a package name"     log:ret:64
    local version="$2";     [ -n "$version" ]   || N=pkg M="Not found $name version"    log:ret:64
    local osarch="$3";      [ -n "$osarch" ]    || N=pkg M="Provide osarch value"

    local download_file_ext=
    local os="${osarch%/*}";  local arch="${osarch#*/}";    local tree=
    ___x_cmd_pkg___attr "$name" "$version" "$osarch" "download_file_ext,tree" || return $?
    local dir="$___X_CMD_PKG_DOWNLOAD_PATH/$name"
    local ball="$dir/${version}.${tree}.${download_file_ext}"
    pkg:debug "Attempting to remove $ball"

    [ ! -f "$ball" ] || ___x_cmd rmrf "$ball" || M="Remove $ball failed" N=pkg log:ret:1
    [ ! -d "$dir" ] || ! ___x_cmd fsiter --dirempty "$dir" || ___x_cmd rmrf "$dir"
    pkg:info "Successfully removed $ball"
}


___x_cmd_pkg_sphere_gc_remove___main(){

    # This is for user interaction
    # if ___x_cmd_pkg_sphere_gc_islinked_ "$pkg"; then
    #     pkg:info "Fail to remove because it is inside linked"
    #     return 1
    # fi

    # if ___x_cmd_pkg_sphere_gc_is_inside_safelist "$pkg"; then
    #     pkg:info "Fail to remove because it is inside safelist"
    #     return 1
    # fi

    ___x_cmd_pkg_sphere_gc_remove___silent \
        --sphere "$sphere_name" --sphereroot "$___X_CMD_PKG_ROOT_SPHERE" \
        --osarch "$osarch" "$name" "$version" "$gcfp"
}



___x_cmd_pkg_sphere_gc_remove___silent(){
    pkg:sphere:parse:option
    sphere_name="${sphere_name:-"X"}"
    local x_=
    local name="$1";
            [ -n "$name" ]      || N=pkg M="Provide a package name"     log:ret:1
    local version="$2";
            [ -n "$version" ]   || {
            x_=; ___x_cmd_pkg_default_version_ "$name" "$osarch"            || return $?
            version="$x_";
    }

    local gcfp="$3";
            [ -f "$gcfp" ]      || N=pkg M="Not found gc start file"    log:ret:1

    # Noitce: you should never
    local fslock_name="$___X_CMD_PKG_ROOT_SPHERE/$sphere_name/$osarch/$name/$version"
    (
        ___x_cmd fslock wait_acquire "$fslock_name" || return $?

        x_=; ___x_cmd_pkg_sphere_lastaddts get_ \
            --sphere "$sphere_name" --sphereroot "$___X_CMD_PKG_ROOT_SPHERE"                \
            --osarch "$osarch" "$name" "$version" || return $?
        if [ -f "$x_" ]; then
            [ "$gcfp" -nt "$x_" ] || {
                pkg:info "The last added time of [osarch=$osarch] [name=$name] [version=$version] is newer than gc start time"
                return 1
            }
            ___x_cmd rmrf "$x_"
        fi

        if ___x_cmd_pkg_sphere_link exist   \
                --sphere "$sphere_name"                     \
                --sphereroot "$___X_CMD_PKG_ROOT_SPHERE"    \
                --osarch "$osarch" "$name" "$version"; then
            pkg:info "GC for [pkg=$name:$version:$osarch] abort because it is inside linked"
            return 1
        fi

        if ___x_cmd_pkg_sphere_safelist exist   \
                --sphere "$sphere_name"                     \
                --sphereroot "$___X_CMD_PKG_ROOT_SPHERE"    \
                --osarch "$osarch" "${name}=${version}"; then
            pkg:info "Fail to remove because it is inside safelist"
            return 1
        fi

        if ___x_cmd_pkg_sphere_depend file exist    \
                --sphere "$sphere_name"                     \
                --sphereroot "$___X_CMD_PKG_ROOT_SPHERE"    \
                --osarch "$osarch" "$name" "$version"; then
            pkg:info "Fail to remove because it is depeneded"
            return 1
        fi

        # TODO: just remove package
        ___x_cmd_pkg_sphere_gc_remove___populate    \
                --sphere "$sphere_name"                     \
                --sphereroot "$___X_CMD_PKG_ROOT_SPHERE"    \
                --osarch "$osarch" "$name" "$version" || return $?

        ___x_cmd fslock release "$fslock_name"
    ) || {
        ___x_cmd fslock release "$fslock_name"
        return 1
    }

    ___x_cmd fslock run "pkg_${name}_${version}_${osarch}" ___x_cmd_pkg_sphere_gc_remove___ball "$name" "$version" "$osarch"
}

