# shellcheck    shell=dash disable=SC2034,SC1090,SC2120

___x_cmd log init pkg

# TODO: check and delete in the future.
xrc:mod path/latest

xrc:mod:lib     pkg \
    envvar      util        sphere/_index   \
    info/ls     info/ll     bootupdate

# TODO: consider -> source $___X_CMD_ROOT_MOD/x-cmd/lwmod/lazysrc
___x_cmd lazysrc    "$___X_CMD_ROOT_MOD/pkg/lib/inner/_ls_urls"     ___x_cmd_pkg__ls_urls   ___x_cmd_pkg__head_test_urls
___x_cmd lazysrc    "$___X_CMD_ROOT_MOD/pkg/lib/info/which"         ___x_cmd_pkg_which      ___x_cmd_pkg_which_
___x_cmd lazysrc    "$___X_CMD_ROOT_MOD/pkg/lib/env/_index"         ___x_cmd_pkg_env
___x_cmd lazyfun    "$___X_CMD_ROOT_MOD/pkg/lib/inner/_smoke"       ___x_cmd_pkg__smoke     \
                    "$___X_CMD_ROOT_MOD/pkg/lib/info/info"          ___x_cmd_pkg_info       \
                    "$___X_CMD_ROOT_MOD/pkg/lib/mutate/download"    ___x_cmd_pkg_download   \
                    "$___X_CMD_ROOT_MOD/pkg/lib/websrc"             ___x_cmd_pkg_websrc

if ___x_cmd_is_suitable_advise_env; then
    ___x_cmd lazyfun    "$___X_CMD_ROOT_MOD/pkg/lib/advise"         ___x_cmd_pkg___advise
fi

___x_cmd_pkg___main(){
    # ___x_cmd_pkg_update___inner || return $?
    [ "$#" -gt 0 ] || set -- --help
    local op="$1"; shift
    case "$op" in
        --help|-h)              ___x_cmd help -m pkg;               return ;;
        bootupdate)             ___x_cmd_pkg_bootupdate "$@";       return ;;
        update_check)           ___x_cmd_pkg_update___check "$@";   return ;;
    esac

    ___x_cmd_is_suitable_pkg || {
        if ___x_cmd_is_termux; then
            pkg:warn "Given Termux's managing packages without requiring root priviledge, x-cmd directly uses native 'pkg' command to resolve dependency."
            return 1
        else
            pkg:error "The pkg module functionality is not supported in the current environment"
            return 1
        fi
    }
    case "$op" in
        ls)                     ___x_cmd_pkg_ls                     "$@" ;;      # add filter, remote, installed, ...
        ll)                     ___x_cmd_pkg_ll                     "$@" ;;
        info)                   ___x_cmd_pkg_info                   "$@" ;;
        which)                  ___x_cmd_pkg_which                  "$@" ;;
        default_version)        ___x_cmd_pkg_default_version        "$@" ;;
        latest_version)         ___x_cmd_pkg_latest_version         "$@" ;;

        # x pkg download             node=v12
        # download)               ___x_cmd_pkg_download               "$@" ;;
        # populate)               ___x_cmd_pkg_sphere_populate        "$@" ;;
        # x pkg activate/deactivate  node=v12
        # addpath)                ___x_cmd_pkg_sphere_path add        "$@" ;;
        # rmpath)                 ___x_cmd_pkg_sphere_path rm         "$@" ;;
        # unlink)                 ___x_cmd_pkg_sphere_link rm         "$@" ;;

        sphere)                 ___x_cmd_pkg_sphere                 "$@" ;;
        add)                    ___x_cmd_pkg_sphere_add             "$@" ;;
        sociality)              ___x_cmd_pkg_sphere_sociality       "$@" ;;
        path)                   ___x_cmd_pkg_sphere_path            "$@" ;;
        link)                   ___x_cmd_pkg_sphere_link            "$@" ;;
        try)                    ___x_cmd_pkg_env try                "$@" ;;
        untry)                  ___x_cmd_pkg_env untry              "$@" ;;
        use)                    ___x_cmd_pkg_env use                "$@" ;;
        unuse)                  ___x_cmd_pkg_env unuse              "$@" ;;
        upgrade)                ___x_cmd_pkg_env upgrade            "$@" ;;

        boot)                   ___x_cmd_pkg_sphere_boot            "$@" ;;
        unboot)                 ___x_cmd_pkg_sphere_unboot          "$@" ;;
        xbin)                   ___x_cmd_pkg_sphere_xbin            "$@" ;;
        snap|exec)              ___x_cmd_pkg_sphere_snap            "$@" ;;
        gc|cleanup)             ___x_cmd_pkg_sphere_gc              "$@" ;;

        websrc)                 ___x_cmd_pkg_websrc                 "$@" ;;
        update)                 ___x_cmd_pkg_update                 "$@" ;;

        _smoke)                 ___x_cmd_pkg__smoke                 "$@" ;;
        _ls_urls)               ___x_cmd_pkg__ls_urls               "$@" ;;
        _head_test_urls)        ___x_cmd_pkg__head_test_urls        "$@" ;;

        *)                      pkg:error "Not found command - 'x pkg $op'"; return 1
    esac
}

___x_cmd_pkg___init(){
    ___x_cmd mkdirp "$___X_CMD_PKG_SHARED" "$___X_CMD_PKG_CACHE_PATH" "$___X_CMD_PKG_DOWNLOAD_PATH"
    ___x_cmd_pkg_sphere_path --activate --sphere X --sphereroot "$___X_CMD_PKG_ROOT_SPHERE"
}

___x_cmd_pkg_update(){
    local X_help_cmd='___x_cmd help -m pkg update'; help:arg:parse
    ___x_cmd_pkg_update___force || {
        pkg:error "Update the $___X_CMD_PKG_VERSION.tar.gz failed"
        return 1 # Force Update
    }
    pkg:info "Update the $___X_CMD_PKG_VERSION.tar.gz success"

    ___x_cmd advise man update x-cmd
}

___x_cmd_pkg_update___inner()(
    local file_path="$___X_CMD_PKG_CACHE_PATH/${___X_CMD_PKG_VERSION}.tar.gz"
    local file_hash_path="$___X_CMD_PKG_CACHE_PATH/${___X_CMD_PKG_VERSION}_hash.txt"
    local tmp_file_path="$___X_CMD_PKG_CACHE_PATH/${___X_CMD_PKG_VERSION}.tar.gz.tmp"
    local tmp_file_hash_path="$___X_CMD_PKG_CACHE_PATH/${___X_CMD_PKG_VERSION}_hash.txt.tmp"
    local x_url_tar=
    local x_url_hash=

    if [ -n "$___X_CMD_PKG_DEV_MOD" ]; then
        pkg:warn "update inner release ${___X_CMD_PKG_VERSION}.tar.gz; ___X_CMD_PKG_DEV_MOD=1"

        x_url_tar="https://codeberg.org/x-cmd-pkg/release/raw/branch/main/dist/${___X_CMD_PKG_VERSION}.tar.gz"
        x_url_hash="https://codeberg.org/x-cmd-pkg/release/raw/branch/main/dist/${___X_CMD_PKG_VERSION}_hash.txt"

        # x_url_tar="https://github.com/x-cmd-pkg/release/raw/main/dist/${___X_CMD_PKG_VERSION}.tar.gz"
        # x_url_hash="https://raw.githubusercontent.com/x-cmd-pkg/release/main/dist/${___X_CMD_PKG_VERSION}_hash.txt"

    elif [ "$___X_CMD_WEBSRC_REGION" != cn ]; then
        x_url_tar="https://github.com/x-cmd/pkg/raw/main/dist/${___X_CMD_PKG_VERSION}.tar.gz"
        x_url_hash="https://raw.githubusercontent.com/x-cmd/pkg/main/dist/${___X_CMD_PKG_VERSION}_hash.txt"
    else
        x_url_tar="https://oss.resource.x-cmd.com/x-cmd/pkg/dist/${___X_CMD_PKG_VERSION}.tar.gz"
        x_url_hash="https://oss.resource.x-cmd.com/x-cmd/pkg/dist/${___X_CMD_PKG_VERSION}_hash.txt"
    fi

    pkg:info "Update PKG resource"
    [ -d "$___X_CMD_PKG_CACHE_PATH" ] || ___x_cmd mkdirp "$___X_CMD_PKG_CACHE_PATH" || return 1
    pkg:info "Download ${___X_CMD_PKG_VERSION}.tar.gz form $x_url_tar"
    ___x_cmd curl -L -sS --speed-time 20 --speed-limit 50 "$x_url_tar" > "$tmp_file_path" || {
        pkg:error "Failed to download pkg metadata configuration files"
        return 1
    }

    pkg:info "Download ${___X_CMD_PKG_VERSION}_hash.txt from $x_url_hash"
    ___x_cmd curl -L -sS --speed-time 20 --speed-limit 50 "$x_url_hash" > "$tmp_file_hash_path" || {
        pkg:error "Failed to download ${___X_CMD_PKG_VERSION}_hash.txt"
        return 1
    }

    local hash_value
    local file_hash
    hash_value="$( < "$tmp_file_hash_path" ___x_cmd_cmds_awk '{print $1}')"
    file_hash="$(___x_cmd sha512 "$tmp_file_path")"


    [ "$hash_value" = "$file_hash" ] || {
        pkg:error "File corrupted; Please check your network status"
        ___x_cmd rmrf "$tmp_file_path" "$tmp_file_hash_path"
        return 1
    }

    ! [ -d "$___X_CMD_PKG_METADATA_PATH/tmp" ] || {
        ___x_cmd rmrf "$___X_CMD_PKG_CACHE_PATH/tmp"
        ___x_cmd mv "$___X_CMD_PKG_METADATA_PATH/tmp" "$___X_CMD_PKG_CACHE_PATH"
    }

    ___x_cmd rmrf "$file_path" "$file_hash_path"
    ___x_cmd mv "$tmp_file_path" "$file_path"
    ___x_cmd mv "$tmp_file_hash_path" "$file_hash_path"

    ___x_cmd rmrf "$___X_CMD_METADATA_FOLDER"
    ___x_cmd mkdirp "$___X_CMD_METADATA_FOLDER"
    pkg:debug --tgt "$___X_CMD_PKG_METADATA_PATH" "Deflate the $file_path"
    ( ___x_cmd_cmds_cd "$___X_CMD_METADATA_FOLDER" && ___X_CMD_ZUZ_QUIET=1 ___x_cmd uz "$file_path" ) || {
        pkg:error "Deflation $file_path failure."
        return 1
    }

    ! [ -d "$___X_CMD_PKG_CACHE_PATH/tmp" ] || ___x_cmd mv "$___X_CMD_PKG_CACHE_PATH/tmp" "$___X_CMD_PKG_METADATA_PATH"

    ___x_cmd ensurefp "$___X_CMD_PKG_FP_UPDATED_DONE"
    printf "%s\n" "" > "$___X_CMD_PKG_FP_UPDATED_DONE"
)

# 86400
___x_cmd_pkg_update___check(){
    [ -f "$___X_CMD_PKG_FP_UPDATED_DONE" ] || ___x_cmd fslock run pkg_update_check ___x_cmd_pkg_update___check_inner
}

___x_cmd_pkg_update___check_inner(){
    [ -f "$___X_CMD_PKG_FP_UPDATED_DONE" ] || ___x_cmd_pkg_update___inner
}

___x_cmd_pkg_update___force(){
    [ ! -f "$___X_CMD_PKG_FP_UPDATED_DONE" ] || ___x_cmd rmrf "$___X_CMD_PKG_FP_UPDATED_DONE"
    ___x_cmd_pkg_update___check
}

___x_cmd_pkg___init
