#!/bin/bash

###############################################################
# 严格模式
set -euo pipefail # 兼容性写法（部分 shell 可能不支持 pipefail）
shopt -s failglob nullglob

# 调试模式（按需启用），用法：DEBUG=true ./install.sh
if [[ "${DEBUG:-}" == "true" ]]; then
  set -xv
fi

# 清理函数
cleanup() {
    echo "清理资源..."
}

# 清理和错误处理
trap 'echo "Error at line $LINENO"; cleanup' ERR
###############################################################

# 配置项
# BUILD_MODE: 编译模式
#   - local: 只编译当前平台（默认）
#   - all: 编译所有平台
BUILD_MODE="${BUILD_MODE:-local}"

# BUILD_CMD: 编译工具
#   - auto: 自动选择（macOS 用 cargo，其他用 zigbuild，推荐）
#   - cargo: 使用原生 cargo（仅适用于本机平台）
#   - zigbuild: 使用 cargo-zigbuild（适用于交叉编译）
BUILD_CMD="${BUILD_CMD:-auto}"

# 目标平台列表
# 使用 cargo-zigbuild 可以在 macOS 上成功编译所有平台
TARGETS=(
    "x86_64-apple-darwin"           # macOS Intel
    "aarch64-apple-darwin"          # macOS Apple Silicon
    "x86_64-unknown-linux-gnu"      # Linux x86_64
    "aarch64-unknown-linux-gnu"     # Linux ARM64
    "x86_64-pc-windows-gnu"         # Windows x86_64
)

# 获取 zigbuild 的目标平台（需要指定 glibc 版本）
get_zigbuild_target() {
    local target="$1"
    case "$target" in
        "x86_64-unknown-linux-gnu")
            echo "x86_64-unknown-linux-gnu.2.28"
            ;;
        "aarch64-unknown-linux-gnu")
            echo "aarch64-unknown-linux-gnu.2.28"
            ;;
        "x86_64-pc-windows-gnu")
            echo "x86_64-pc-windows-gnu"
            ;;
        *)
            echo "$target"
            ;;
    esac
}

cd .. && pwd
cargo clean

# 目录配置
INSTALL_DIR="$HOME/data/bin"
RELEASE_DIR="./target/releases"
mkdir -p "$INSTALL_DIR"
mkdir -p "$RELEASE_DIR"

# 获取当前平台
CURRENT_PLATFORM=$(rustc -vV | grep "host:" | cut -d' ' -f2)

# 根据编译模式确定要编译的平台
if [[ "$BUILD_MODE" == "all" ]]; then
    echo "==> 多平台编译模式，使用 $BUILD_CMD"
    BUILD_TARGETS=("${TARGETS[@]}")
else
    echo "==> 本地编译模式，仅编译当前平台: $CURRENT_PLATFORM"
    BUILD_TARGETS=("$CURRENT_PLATFORM")
fi

# 检查是否安装了 cargo-zigbuild
check_zigbuild() {
    if ! command -v cargo-zigbuild &> /dev/null; then
        echo "⚠️  警告: 未安装 cargo-zigbuild"
        echo "请运行: cargo install cargo-zigbuild"
        exit 1
    fi
}

# 遍历所有目标平台进行编译
for target in "${BUILD_TARGETS[@]}"; do
    echo ""
    echo "==> 编译目标平台: $target"

    # 确定使用的编译工具和目标平台
    actual_target="$target"
    build_tool="cargo"

    if [[ "$BUILD_CMD" == "auto" ]]; then
        # 自动选择：macOS 用 cargo，其他用 zigbuild
        if [[ "$target" == *"darwin"* ]]; then
            build_tool="cargo"
        else
            build_tool="cargo-zigbuild"
            # 使用 zigbuild 的目标平台（带 glibc 版本）
            actual_target=$(get_zigbuild_target "$target")
        fi
    elif [[ "$BUILD_CMD" == "zigbuild" ]]; then
        build_tool="cargo-zigbuild"
        actual_target=$(get_zigbuild_target "$target")
    else
        build_tool="cargo"
    fi

    # 检查 zigbuild 是否已安装
    if [[ "$build_tool" == "cargo-zigbuild" ]]; then
        check_zigbuild
    fi

    echo "    使用工具: $build_tool"
    echo "    目标平台: $actual_target"

    # 编译所有二进制工具
    $build_tool build --release --bins --target "$actual_target"

    # 仅在多平台模式下创建发布目录
    if [[ "$BUILD_MODE" == "all" ]]; then
        platform_dir="$RELEASE_DIR/$target"
        mkdir -p "$platform_dir"

        # 复制编译后的二进制文件到发布目录
        for rs_file in src/bin/*.rs; do
            bin_name=$(basename "$rs_file" .rs)

            # Windows 平台需要加 .exe 后缀
            # 注意：zigbuild 生成的文件路径使用原始 target，不带 glibc 版本
            if [[ "$target" == *"windows"* ]]; then
                src_bin="./target/$target/release/${bin_name}.exe"
                dst_bin="$platform_dir/${bin_name}.exe"
            else
                src_bin="./target/$target/release/$bin_name"
                dst_bin="$platform_dir/$bin_name"
            fi

            if [[ -f "$src_bin" ]]; then
                cp -fv "$src_bin" "$dst_bin"
                chmod +x "$dst_bin" 2>/dev/null || true  # Windows 文件跳过 chmod
                echo "  ✅ 打包: $bin_name -> $dst_bin"
            else
                echo "  ⚠️  警告: 未找到编译后的二进制文件: $src_bin"
            fi
        done
    fi
done

# 安装当前平台的版本到 ~/data/bin
echo ""
echo "==> 安装当前平台 ($CURRENT_PLATFORM) 的二进制工具到 $INSTALL_DIR"

for rs_file in src/bin/*.rs; do
    bin_name=$(basename "$rs_file" .rs)

    # 在多平台模式下，从 releases 目录安装（避免后续清理删除源文件）
    if [[ "$BUILD_MODE" == "all" ]]; then
        # 从 releases 目录获取当前平台的二进制文件
        platform_name=""
        case "$CURRENT_PLATFORM" in
            *"darwin"*)
                platform_name="$CURRENT_PLATFORM"
                ;;
            *"linux"*)
                platform_name="$CURRENT_PLATFORM"
                ;;
            *"windows"*)
                platform_name="$CURRENT_PLATFORM"
                bin_name="${bin_name}.exe"
                ;;
        esac
        src_bin="$RELEASE_DIR/$platform_name/$bin_name"
    else
        src_bin="./target/$CURRENT_PLATFORM/release/$bin_name"
    fi

    if [[ -f "$src_bin" ]]; then
        echo -n "  ✅ 安装: $bin_name -> " && cp -fv "$src_bin" "$INSTALL_DIR/"
        chmod +x "$INSTALL_DIR/$bin_name" 2>/dev/null || true
    else
        echo "  ⚠️  警告: 未找到编译后的二进制文件: $src_bin"
    fi
done

echo ""
if [[ "$BUILD_MODE" == "all" ]]; then
    echo "==> 多平台编译完成！"
    echo "    所有平台的二进制文件位于: $RELEASE_DIR"
    echo "    当前平台的工具已安装到: $INSTALL_DIR"

    # 清理中间文件，只保留 releases 目录
    echo ""
    echo "==> 清理中间文件..."
    # 删除所有平台的构建目录和 release 目录，保留 releases
    for dir in ./target/*/; do
        dir_name=$(basename "$dir")
        if [[ "$dir_name" != "releases" ]]; then
            rm -rf "$dir"
            echo "    清理: $dir_name"
        fi
    done
    # 删除 .rustc_info.json
    rm -f ./target/.rustc_info.json 2>/dev/null || true
    echo "    ✅ 已清理编译缓存，保留最终产物"
else
    echo "==> 本地编译完成！"
    echo "    工具已安装到: $INSTALL_DIR"
fi