#!/bin/bash

# ========================================
#            常量配置区 (Constants)
# ========================================
GO_BASE_DIR="/sf/data/local/go"
GOPATH="/sf/data/local/gopath"
DOWNLOAD_MIRROR="https://mirrors.aliyun.com/golang"
GO_OS="linux"
TMP_DIR="/tmp"
GOPROXY="https://mirrors.aliyun.com/goproxy,direct"
GO111MODULE_VALUE="auto"
SCRIPT_NAME="dzf_gotool.sh"
# ----------------------------------------
# 自动检测架构 (amd64 | arm64)
# ----------------------------------------
detect_arch() {
    local kernel_arch=$(uname -m)
    case "$kernel_arch" in
        "x86_64"  ) echo "amd64" ;;
        "aarch64" | "arm64" ) echo "arm64" ;;
        *) echo "$kernel_arch" >&2; return 1 ;;
    esac
}

# 避免重复定义 AUTO_ARCH
if ! declare -p AUTO_ARCH &>/dev/null 2>&1; then
    readonly AUTO_ARCH="$(detect_arch)"
    if [ -z "$AUTO_ARCH" ]; then
        echo "❌ 不支持的架构：$(uname -m)，仅支持 x86_64 和 aarch64" >&2
        return 1 2>/dev/null || exit 1
    fi
fi

# 临时文件路径 (避免重复定义)
if ! declare -p VERSION_LIST_TMP &>/dev/null 2>&1; then
    readonly VERSION_LIST_TMP="${TMP_DIR}/go_versions_aliyun.html"
fi

# ========================================
#             函数实现区
# ========================================

ensure_dirs() {
    mkdir -p "$GO_BASE_DIR"
    mkdir -p "$GOPATH"/{src,bin,pkg}
}

# =============== 获取可用版本（含架构） ===============
fetch_available_versions_from_aliyun() {
    local url="${DOWNLOAD_MIRROR}/"
    local tmpfile="$VERSION_LIST_TMP"

    if ! curl -s -f -o "$tmpfile" "$url"; then
        echo "❌ 无法从 $url 获取版本列表，请检查网络" >&2
        # 兜底版本
        echo "1.22.6 amd64"
        echo "1.22.6 arm64"
        echo "1.21.13 amd64"
        rm -f "$tmpfile"
        return
    fi

    grep -o 'go[0-9]\+\.[0-9]\+\.[0-9]\+\.linux-\(amd64\|arm64\)\.tar\.gz' "$tmpfile" | \
        sed -E 's/^go([0-9]+\.[0-9]+\.[0-9]+)\.linux-(amd64|arm64)\.tar\.gz$/\1 \2/' | \
        sort -V | uniq

    rm -f "$tmpfile"
}

# =============== 获取已安装版本 ===============
list_installed_versions() {
    find "$GO_BASE_DIR" -maxdepth 1 -name "go*[0-9]-*" -type d 2>/dev/null | \
        while read dir; do
            basename "$dir" | sed -E 's/^go([0-9]+\.[0-9]+\.[0-9]+)-(amd64|arm64)$/\1 \2/'
        done | sort -V
}

# =============== 自动选择当前架构最新版 ===============
auto_select_latest_for_current_arch() {
    local installed_versions
    mapfile -t installed_versions < <(list_installed_versions)

    local candidates=()
    for v in "${installed_versions[@]:-}"; do
        local arch="${v#* }"
        if [ "$arch" = "$AUTO_ARCH" ]; then
            candidates+=("$v")
        fi
    done

    if [ ${#candidates[@]} -eq 0 ]; then
        echo "❌ 当前架构 ($AUTO_ARCH) 未安装任何 Go 版本。" >&2
        return 1
    fi

    printf '%s\n' "${candidates[@]}" | sort -V | tail -1
}

# =============== 交互式选择 ===============
choose_from_list() {
    local title="$1"
    shift
    local options=("$@")

    if [ ${#options[@]} -eq 0 ]; then
        echo "❌ 无可用选项。" >&2
        return 1
    fi

    echo "$title"
    for i in "${!options[@]}"; do
        local ver="${options[i]%% *}"
        local arch="${options[i]#* }"
        local mark=""
        if [ "$arch" = "$AUTO_ARCH" ]; then
            mark=" (推荐)"
        fi
        echo "  $((i+1))) go$ver-$arch$mark"
    done
    echo
    read -p "请选择 (输入序号, 回车默认自动选择最新): " choice

    if [ -z "$choice" ]; then
        auto_select_latest_for_current_arch
        return $?
    elif [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#options[@]}" ]; then
        selected="${options[$((choice-1))]}"
        return 0
    else
        echo "❌ 无效选择。" >&2
        return 1
    fi
}

# =============== 安装指定版本 ===============
install_go_version() {
    local version=$(echo "$selected" | awk '{print $1}')
    local arch=$(echo "$selected" | awk '{print $2}')
    local filename="go${version}.linux-${arch}.tar.gz"
    local url="${DOWNLOAD_MIRROR}/${filename}"
    local target_dir="${GO_BASE_DIR}/go${version}-${arch}"

    # 检查是否已存在
    if [ -d "$target_dir" ]; then
        echo "⚠️  目录已存在: $target_dir"
        read -p "是否删除并重新安装？[y/N] " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            echo "🛑 取消安装。"
            return 0
        fi
        rm -rf "$target_dir"
        echo "🗑️  已删除旧版本。"
    fi

    echo "⏬ 正在下载: $url"
    local tmpfile="${TMP_DIR}/$filename"
    if ! curl -L -s -o "$tmpfile" "$url"; then
        echo "❌ 下载失败: $url" >&2
        rm -f "$tmpfile"
        return 1
    fi

    echo "📦 安装到: $target_dir"
    mkdir -p "$target_dir"
    if ! tar -xzf "$tmpfile" -C "$target_dir" --strip-components=1; then
        echo "❌ 解压失败" >&2
        rm -rf "$target_dir"
        rm -f "$tmpfile"
        return 1
    fi

    rm -f "$tmpfile"
    echo "✅ 成功安装 Go $version ($arch)"
}

# =============== 安装命令 ===============
cmd_install() {
    echo "🔄 正在从阿里云获取可用的 Go 版本..."
    mapfile -t versions < <(fetch_available_versions_from_aliyun)

    if [ ${#versions[@]} -eq 0 ]; then
        echo "❌ 未能获取任何可用版本。" >&2
        return 1
    fi

    if ! choose_from_list "🔍 选择要安装的 Go 版本:" "${versions[@]}"; then
        return 1
    fi

    install_go_version
}

# =============== 切换命令 ===============
cmd_change() {
    mapfile -t installed < <(list_installed_versions)

    if [ ${#installed[@]} -eq 0 ]; then
        echo "❌ 当前没有已安装的 Go 版本，请先运行: ${SCRIPT_NAME} install" >&2
        return 1
    fi

    local auto_mode=false
    if [ "$1" = "--auto" ]; then
        auto_mode=true
    fi

    if [ "$auto_mode" = true ]; then
        selected=$(auto_select_latest_for_current_arch)
        if [ $? -ne 0 ]; then
            return 1
        fi
    else
        if ! choose_from_list "🚀 选择要加载的 Go 版本（回车自动选择当前架构最新版）:" "${installed[@]}"; then
            return 1
        fi
    fi

    local version=$(echo "$selected" | awk '{print $1}')
    local arch=$(echo "$selected" | awk '{print $2}')
    local target_dir="${GO_BASE_DIR}/go${version}-${arch}"

    if [ ! -d "$target_dir" ]; then
        echo "❌ 目录不存在: $target_dir" >&2
        return 1
    fi

    if [ ! -f "$target_dir/bin/go" ]; then
        echo "❌ Go 可执行文件不存在: $target_dir/bin/go" >&2
        return 1
    fi

    # ✅ 设置环境变量
    export GOROOT="$target_dir"
    export GOPATH="$GOPATH"
    export GO111MODULE="$GO111MODULE_VALUE"
    export GOPROXY="$GOPROXY"
    export PATH="$GOROOT/bin:$GOPATH/bin:$PATH"

    echo "🎮 已切换到 $($GOROOT/bin/go version) [$arch]"
}

# =============== 主入口 ===============
main() {
    ensure_dirs

    case "${1:-}" in
        "install")
            cmd_install
            ;;
        "")
            # 如果没有传参，判断是否通过 source 执行
            if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
                # 直接执行，给出提示
                echo "💡 提示：要让 Go 环境变量在当前 shell 中生效，请使用:"
                echo "   source $0"
            else
                # 通过 source 执行，进入交互式选择模式
                cmd_change "$@"
            fi
            ;;
        *)
            # 其他参数都传递给 cmd_change (如 --auto)
            if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
                echo "💡 提示：要让 Go 环境变量在当前 shell 中生效，请使用:"
                echo "   source $0 $*"
            else
                cmd_change "$@"
            fi
            ;;
    esac
}

# =============== 启动 ===============

main "$@"

