#!/usr/bin/env bash
# build-android.sh — gomobile bind sing-box libbox → dist/android/libbox.aar
#
# 用法: ./build-android.sh [--force]
#   --force  忽略已有产物，强制重新构建
#
# 依赖:
#   - Go     : VERSION 中 GO_VERSION 指定的版本（$GOROOT 或 PATH 中的 go）
#   - gomobile: 脚本自动安装至 $GOPATH/bin，依赖 GOMOBILE_VERSION
#   - Android NDK: 需设置 ANDROID_NDK_HOME 或 ANDROID_HOME（含 ndk-bundle/ndk/<ver>）
#
# 产物: dist/android/libbox.aar
#   包含三个 ABI: arm64-v8a / armeabi-v7a / x86_64
#
# Build tags 说明（对齐官方 SFA — sing-box for Android）:
#   with_quic      — QUIC/HTTP3 协议支持（Hysteria2 必须）
#   with_utls      — uTLS 指纹模拟（TLS 防检测）
#   with_clash_api — Clash 兼容 API（面板控制必须）
#   with_gvisor    — gVisor TUN 网络栈（高性能 TUN 回退）
#
# 裁剪开关（按需取消注释）:
#   with_grpc      — gRPC 入站（约 +4 MB so 体积）
#   with_ech       — TLS ECH 扩展（约 +0.5 MB）
#   with_wireguard — WireGuard 出站（约 +2 MB）

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# ── 加载版本锚点 ─────────────────────────────────────────────────────────────
# shellcheck source=VERSION
. "${SCRIPT_DIR}/VERSION"

# ── 参数解析 ─────────────────────────────────────────────────────────────────
FORCE=false
for arg in "$@"; do
    case "${arg}" in
        --force) FORCE=true ;;
        *) printf 'Unknown argument: %s\n' "${arg}" >&2; exit 1 ;;
    esac
done

# ── 路径配置 ─────────────────────────────────────────────────────────────────
DIST_DIR="${SCRIPT_DIR}/dist/android"
OUT_AAR="${DIST_DIR}/libbox.aar"
BUILD_SRC="${SCRIPT_DIR}/.build/singbox"

# ── Build tags ────────────────────────────────────────────────────────────────
BUILD_TAGS="with_quic,with_utls,with_clash_api,with_gvisor"
# 取消注释以增加功能（会增大 .so 体积）:
# BUILD_TAGS="${BUILD_TAGS},with_grpc"
# BUILD_TAGS="${BUILD_TAGS},with_ech"
# BUILD_TAGS="${BUILD_TAGS},with_wireguard"

# ── 幂等检查 ─────────────────────────────────────────────────────────────────
if [[ "${FORCE}" == false && -f "${OUT_AAR}" ]]; then
    printf '✓ %s 已存在，跳过构建（传 --force 强制重建）\n' "${OUT_AAR}"
    exit 0
fi

# ── 前置检查 ─────────────────────────────────────────────────────────────────
printf '==> 检查前置依赖…\n'

if ! command -v go >/dev/null 2>&1; then
    printf '✗ go 未找到，请安装 Go %s\n' "${GO_VERSION}" >&2
    exit 1
fi
if ! command -v git >/dev/null 2>&1; then
    printf '✗ git 未找到\n' >&2
    exit 1
fi

ACTUAL_GO="$(go version | awk '{print $3}' | sed 's/go//')"
printf '    Go 版本: %s（期望 %s）\n' "${ACTUAL_GO}" "${GO_VERSION}"

if [[ -n "${ANDROID_NDK_HOME:-}" ]]; then
    printf '    NDK: %s\n' "${ANDROID_NDK_HOME}"
elif [[ -n "${ANDROID_HOME:-}" ]]; then
    printf '    Android SDK: %s（gomobile 将自动定位 NDK）\n' "${ANDROID_HOME}"
else
    printf '⚠  未设置 ANDROID_NDK_HOME / ANDROID_HOME，gomobile init 可能失败\n' >&2
fi

# ── 安装 gomobile ─────────────────────────────────────────────────────────────
printf '==> 安装 gomobile@%s…\n' "${GOMOBILE_VERSION}"
go install "golang.org/x/mobile/cmd/gomobile@${GOMOBILE_VERSION}"
go install "golang.org/x/mobile/cmd/gobind@${GOMOBILE_VERSION}"

printf '==> gomobile init…\n'
gomobile init

# ── 准备 sing-box 源码 ────────────────────────────────────────────────────────
printf '==> 准备 sing-box %s 源码…\n' "${SINGBOX_VERSION}"

EXISTING_TAG=""
if [[ -d "${BUILD_SRC}/.git" ]]; then
    EXISTING_TAG="$(git -C "${BUILD_SRC}" describe --tags --exact-match 2>/dev/null)" || EXISTING_TAG="unknown"
fi

if [[ "${EXISTING_TAG}" == "${SINGBOX_VERSION}" ]]; then
    printf '    源码已是 %s，跳过克隆\n' "${SINGBOX_VERSION}"
else
    if [[ -d "${BUILD_SRC}" ]]; then
        printf '    已有源码版本 %s ≠ %s，清理后重新克隆…\n' "${EXISTING_TAG}" "${SINGBOX_VERSION}"
        rm -rf "${BUILD_SRC}"
    fi
    mkdir -p "${BUILD_SRC%/*}"
    git clone --depth 1 --branch "${SINGBOX_VERSION}" \
        https://github.com/SagerNet/sing-box.git "${BUILD_SRC}"
fi

# ── 构建 AAR ──────────────────────────────────────────────────────────────────
printf '==> 构建 libbox.aar\n'
printf '    target : android/arm64,android/arm,android/amd64\n'
printf '    api    : 21\n'
printf '    tags   : %s\n' "${BUILD_TAGS}"

mkdir -p "${DIST_DIR}"

(
    cd "${BUILD_SRC}"
    go mod download
    gomobile bind \
        -target android/arm64,android/arm,android/amd64 \
        -androidapi 21 \
        -tags "${BUILD_TAGS}" \
        -o "${OUT_AAR}" \
        ./experimental/libbox
)

printf '\n✓ 构建完成: %s\n' "${OUT_AAR}"
printf '  ABI 验证（.so 文件列表）:\n'
unzip -l "${OUT_AAR}" | grep -E '\.so$' | awk '{print "    " $NF}' || true
