#!/usr/bin/env bash
# =============================================================================
# WZ Phone — Android APK build script for Debian 12 (Bookworm)
#
# Sets up a complete build environment from scratch and produces a debug APK.
# Idempotent — safe to run multiple times (skips already-installed components).
#
# Tested on: Debian 12 x86_64, cross-compiling to aarch64-linux-android
#
# Why these specific versions:
#
#   cmake 3.25-3.28 (system package from apt)
#     cmake 3.25 (Debian 12) and 3.28 (Ubuntu 24.04) both work.
#     cmake 3.31+ has armv7/aarch64 flag conflicts in Android-Determine.cmake.
#     cmake 4.x drops cmake_minimum_required < 3.5.
#     Do NOT use pip cmake — it bundles its own modules with different bugs.
#     CRITICAL: must set ANDROID_NDK=$ANDROID_NDK_HOME (cmake checks ANDROID_NDK).
#
#   NDK 26.1.10909125 (r26b)
#     NDK 27+ ships a newer libc++_shared.so with different scudo allocator
#     defaults. On Android 16 devices with MTE (Memory Tagging Extension)
#     enabled (e.g. Nothing A059), NDK 27's scudo crashes during malloc/calloc.
#     NDK 26.1 is the last stable version for these devices.
#     Matches build.gradle.kts: ndkVersion = "26.1.10909125"
#
#   JDK 17 (openjdk-17-jdk-headless)
#     Gradle 8.5 + AGP 8.2.0 officially support JDK 17.
#     JDK 21 works for compilation but has Gradle daemon compat issues.
#
#   Rust stable (currently 1.94.1)
#     Edition 2024, MSRV 1.85. Stable channel is fine.
#
#   ANDROID_NDK=$ANDROID_NDK_HOME (BOTH must be set)
#     cmake's Android platform module checks ANDROID_NDK (no _HOME suffix).
#     cargo-ndk sets ANDROID_NDK_HOME. Both must point to the same path.
#
# Usage:
#   chmod +x scripts/build-android.sh
#   ./scripts/build-android.sh                    # build from current tree
#   WZP_CLONE=1 ./scripts/build-android.sh        # clone fresh from git
#   WZP_COMMIT=2092245 ./scripts/build-android.sh  # pin to specific commit
#
# Environment variables (all optional):
#   WZP_CLONE       Set to 1 to clone from git instead of using current dir
#   WZP_REPO        Git clone URL        (default: ssh://git@git.manko.yoga:222/manawenuz/wz-phone)
#   WZP_BRANCH      Branch to checkout   (default: feat/android-voip-client)
#   WZP_COMMIT      Commit to pin to     (default: HEAD)
#   WZP_WORKDIR     Build directory       (default: /tmp/wzp-build)
#   ANDROID_API     SDK platform level    (default: 34)
#   NDK_VERSION     NDK version string    (default: 26.1.10909125)
# =============================================================================
set -euo pipefail

# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
CLONE="${WZP_CLONE:-0}"
REPO="${WZP_REPO:-ssh://git@git.manko.yoga:222/manawenuz/wz-phone}"
BRANCH="${WZP_BRANCH:-feat/android-voip-client}"
COMMIT="${WZP_COMMIT:-}"
WORKDIR="${WZP_WORKDIR:-/tmp/wzp-build}"
ANDROID_API="${ANDROID_API:-34}"
NDK_VERSION="${NDK_VERSION:-26.1.10909125}"

ANDROID_HOME="${ANDROID_HOME:-$HOME/android-sdk}"
ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$NDK_VERSION"
# cmake checks ANDROID_NDK (not _HOME) — both must be set
ANDROID_NDK="$ANDROID_NDK_HOME"
JAVA_HOME="/usr/lib/jvm/java-17-openjdk-$(dpkg --print-architecture)"
CMDLINE_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"

export ANDROID_HOME ANDROID_NDK_HOME ANDROID_NDK JAVA_HOME
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$HOME/.cargo/bin:$PATH"

log() { echo -e "\n\033[1;36m>>> $*\033[0m"; }
err() { echo -e "\033[1;31mERROR: $*\033[0m" >&2; exit 1; }

# ---------------------------------------------------------------------------
# Step 1: System packages (cmake 3.25, JDK 17, make, git, etc.)
# ---------------------------------------------------------------------------
log "Installing system packages"
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq \
    build-essential \
    cmake \
    curl \
    git \
    libssl-dev \
    pkg-config \
    unzip \
    wget \
    zip \
    openjdk-17-jdk-headless \
    2>/dev/null

# Verify critical versions
log "Verifying build environment"
echo "  cmake:  $(cmake --version | head -1)"
echo "  java:   $(java -version 2>&1 | head -1)"
echo "  make:   $(make --version | head -1)"

CMAKE_MAJOR=$(cmake --version | head -1 | grep -oP '\d+' | head -1)
CMAKE_MINOR=$(cmake --version | head -1 | grep -oP '\d+' | sed -n '2p')
if [ "$CMAKE_MAJOR" -gt 3 ] || { [ "$CMAKE_MAJOR" -eq 3 ] && [ "$CMAKE_MINOR" -gt 30 ]; }; then
    err "cmake $(cmake --version | head -1) is too new! Need cmake <= 3.28.x. cmake 3.31+ has Android cross-compilation bugs."
fi

# ---------------------------------------------------------------------------
# Step 2: Rust toolchain
# ---------------------------------------------------------------------------
log "Setting up Rust toolchain"
if ! command -v rustup &>/dev/null; then
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
    source "$HOME/.cargo/env"
fi
rustup default stable
rustup target add aarch64-linux-android
echo "  rustc:  $(rustc --version)"
echo "  cargo:  $(cargo --version)"

if ! command -v cargo-ndk &>/dev/null; then
    log "Installing cargo-ndk"
    cargo install cargo-ndk
fi
echo "  ndk:    $(cargo ndk --version)"

# ---------------------------------------------------------------------------
# Step 3: Android SDK + NDK 26.1
# ---------------------------------------------------------------------------
log "Setting up Android SDK + NDK $NDK_VERSION"
if [ ! -f "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]; then
    log "Downloading Android command-line tools"
    mkdir -p "$ANDROID_HOME/cmdline-tools"
    TMPZIP=$(mktemp /tmp/cmdline-tools-XXXXX.zip)
    wget -q -O "$TMPZIP" "$CMDLINE_TOOLS_URL"
    unzip -qo "$TMPZIP" -d "$ANDROID_HOME/cmdline-tools"
    mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest" 2>/dev/null || true
    rm -f "$TMPZIP"
fi

yes | sdkmanager --licenses >/dev/null 2>&1 || true

if [ ! -d "$ANDROID_NDK_HOME" ]; then
    log "Installing NDK $NDK_VERSION (this takes a few minutes)"
    sdkmanager --install \
        "platforms;android-${ANDROID_API}" \
        "build-tools;${ANDROID_API}.0.0" \
        "ndk;${NDK_VERSION}" \
        "platform-tools" \
        2>&1 | grep -v "^\[" || true
fi

[ -d "$ANDROID_NDK_HOME" ] || err "NDK not found at $ANDROID_NDK_HOME"
echo "  NDK:    $ANDROID_NDK_HOME"
echo "  SDK:    $ANDROID_HOME"

# ---------------------------------------------------------------------------
# Step 4: Source code
# ---------------------------------------------------------------------------
if [ "$CLONE" = "1" ]; then
    log "Cloning $REPO (branch: $BRANCH)"
    if [ -d "$WORKDIR/.git" ]; then
        cd "$WORKDIR"
        git fetch origin
    else
        rm -rf "$WORKDIR"
        git clone --branch "$BRANCH" --recurse-submodules "$REPO" "$WORKDIR"
        cd "$WORKDIR"
    fi
    git checkout "$BRANCH"
    git pull origin "$BRANCH" || true
    git submodule update --init --recursive

    if [ -n "$COMMIT" ]; then
        log "Pinning to commit $COMMIT"
        git checkout "$COMMIT"
    fi
else
    # Use current directory (assume we're in the repo root)
    SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
    WORKDIR="$(cd "$SCRIPT_DIR/.." && pwd)"
    cd "$WORKDIR"
    [ -f "Cargo.toml" ] || err "Not in repo root. Run from repo root or set WZP_CLONE=1"
fi

echo "  HEAD:   $(git log --oneline -1)"

# ---------------------------------------------------------------------------
# Step 5: Build native Rust library (.so)
# ---------------------------------------------------------------------------
log "Building Rust native library (arm64-v8a, release)"
cargo ndk -t arm64-v8a \
    -o "$WORKDIR/android/app/src/main/jniLibs" \
    build --release -p wzp-android

SO="$WORKDIR/android/app/src/main/jniLibs/arm64-v8a/libwzp_android.so"
[ -f "$SO" ] || err ".so not found at $SO"
echo "  Built:  $SO ($(du -h "$SO" | cut -f1))"

# ---------------------------------------------------------------------------
# Step 6: Generate debug keystore (if missing)
# ---------------------------------------------------------------------------
KEYSTORE="$WORKDIR/android/keystore/wzp-debug.jks"
if [ ! -f "$KEYSTORE" ]; then
    log "Generating debug keystore"
    mkdir -p "$(dirname "$KEYSTORE")"
    keytool -genkey -v \
        -keystore "$KEYSTORE" \
        -keyalg RSA -keysize 2048 -validity 10000 \
        -alias wzp-debug \
        -storepass android -keypass android \
        -dname "CN=WZP Debug" 2>&1 | tail -1
fi

# ---------------------------------------------------------------------------
# Step 7: Build Android APK
# ---------------------------------------------------------------------------
log "Building APK (debug)"
cd "$WORKDIR/android"
chmod +x ./gradlew
./gradlew assembleDebug --no-daemon --warning-mode=none

APK=$(find . -name "app-debug*.apk" -path "*/outputs/apk/*" | head -1)
[ -n "$APK" ] || err "APK not found"
APK_ABS="$(cd "$(dirname "$APK")" && pwd)/$(basename "$APK")"

# ---------------------------------------------------------------------------
# Done
# ---------------------------------------------------------------------------
log "Build complete!"
echo ""
echo "  ┌──────────────────────────────────────────────────────────┐"
echo "  │ APK:    $APK_ABS"
echo "  │ Size:   $(du -h "$APK_ABS" | cut -f1)"
echo "  │ SHA256: $(sha256sum "$APK_ABS" | cut -d' ' -f1)"
echo "  └──────────────────────────────────────────────────────────┘"
echo ""
echo "  Install:  adb install -r $APK_ABS"
echo ""
