#!/usr/bin/env bash
# Cross-compile VICE 3.8 headless as a static library for Android.
# Called automatically by Gradle; can also be run manually:
#   export NDK=/path/to/android-ndk && bash build_vice.sh
#
# Output: vice-libs/arm64-v8a/libvice.a
#         vice-libs/x86_64/libvice.a

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TARBALL="${SCRIPT_DIR}/../../../../res/vice-3.8.tar.gz"
SRC="${SCRIPT_DIR}/vice-src"

: "${NDK:?NDK env var must point to the Android NDK root}"

echo "=== build_vice.sh ==="
echo "  SCRIPT_DIR : ${SCRIPT_DIR}"
echo "  TARBALL    : ${TARBALL}"
echo "  SRC        : ${SRC}"
echo "  NDK        : ${NDK}"

# ---- Validate NDK toolchain -----------------------------------------------
TOOLCHAIN="${NDK}/toolchains/llvm/prebuilt/linux-x86_64"
if [ ! -d "${TOOLCHAIN}" ]; then
    echo "ERROR: NDK toolchain not found at ${TOOLCHAIN}" >&2
    echo "  Installed NDK contents:" >&2
    ls "${NDK}" 2>&1 || true
    exit 1
fi
echo "  TOOLCHAIN  : ${TOOLCHAIN} [OK]"

# ---- Ensure required host tools are present ---------------------------------
MISSING=()
for tool in dos2unix autoconf automake pkg-config xa flex; do
    command -v "$tool" &>/dev/null || MISSING+=("$tool")
done
if [ ${#MISSING[@]} -gt 0 ]; then
    echo "ERROR: Missing required build tools: ${MISSING[*]}" >&2
    echo "  Install with: sudo apt-get install -y ${MISSING[*]/xa/xa65}" >&2
    exit 1
fi

# ---- Validate tarball -------------------------------------------------------
if [ ! -f "${TARBALL}" ]; then
    echo "ERROR: VICE tarball not found at ${TARBALL}" >&2
    exit 1
fi
echo "  TARBALL found [OK]"

# ---- Unpack once ------------------------------------------------------------
if [ ! -d "${SRC}" ]; then
    echo "Unpacking VICE 3.8..."
    tar -xzf "${TARBALL}" -C "${SCRIPT_DIR}"
    mv "${SCRIPT_DIR}/vice-3.8" "${SRC}"
    echo "Unpacked to ${SRC}"
fi

# ---- Run autogen if configure is missing ------------------------------------
if [ ! -f "${SRC}/configure" ]; then
    echo "Running autogen.sh..."
    pushd "${SRC}" >/dev/null
    ./autogen.sh
    popd >/dev/null
fi

# ---- Build per ABI ----------------------------------------------------------
build_abi() {
    local ABI="$1"
    local HOST="$2"
    local API=24
    local CC="${TOOLCHAIN}/bin/${HOST}${API}-clang"
    local CXX="${TOOLCHAIN}/bin/${HOST}${API}-clang++"
    local AR="${TOOLCHAIN}/bin/llvm-ar"
    local OUT="${SCRIPT_DIR}/vice-libs/${ABI}"
    local BUILD_DIR="/tmp/vice-android-${ABI}"

    echo ""
    echo "--- ABI: ${ABI} ---"
    echo "  CC  : ${CC}"
    echo "  CXX : ${CXX}"
    echo "  AR  : ${AR}"
    echo "  OUT : ${OUT}"

    if [ -f "${OUT}/libvice.a" ] && [ -f "${OUT}/config.h" ]; then
        echo "  libvice.a + config.h already exist — skipping"
        return 0
    fi

    if [ ! -f "${CC}" ]; then
        echo "ERROR: Clang not found at ${CC}" >&2
        echo "  Available clang binaries:" >&2
        ls "${TOOLCHAIN}/bin/"*clang* 2>&1 || true
        exit 1
    fi
    if [ ! -f "${CXX}" ]; then
        echo "ERROR: Clang++ not found at ${CXX}" >&2
        ls "${TOOLCHAIN}/bin/"*clang* 2>&1 || true
        exit 1
    fi

    mkdir -p "${BUILD_DIR}" "${OUT}"
    pushd "${BUILD_DIR}" >/dev/null

    echo "  Configuring VICE..."
    CC="${CC}" CXX="${CXX}" AR="${AR}" \
    CFLAGS="-fPIC" CXXFLAGS="-fPIC" \
    "${SRC}/configure" \
        --host="${HOST}" \
        --srcdir="${SRC}" \
        --enable-headlessui \
        --without-libcurl \
        --without-png \
        --without-alsa \
        --without-pulse \
        --without-libieee1284 \
        --enable-arch=no \
        --disable-dependency-tracking \
        --disable-debug

    echo "  Compiling VICE sub-libraries..."
    # Build all sub-libraries; tolerate failure of the final x64 link step
    # (which may fail due to optional deps like linenoise-ng not being a sub-lib dep)
    make -C src -j"$(nproc)" || echo "  NOTE: make exited non-zero — sub-libraries are still usable"

    echo "  Archiving into libvice.a..."
    OBJ_TMPDIR=$(mktemp -d)
    CTR=0

    # 1. Standalone .o files compiled directly in BUILD_DIR/src/
    #    (core objects: alarm.o keyboard.o attach.o etc.)
    for obj in "${BUILD_DIR}/src"/*.o; do
        [ -f "$obj" ] || continue
        base=$(basename "$obj")
        case "$base" in
            vsyncapi.o|c1541-stubs.o|vsid-stubs.o) continue ;;
        esac
        cp "$obj" "${OBJ_TMPDIR}/${CTR}_${base}"
        CTR=$((CTR+1))
    done

    # 2. Extract objects from sub-library .a files, skipping non-C64 machines
    while IFS= read -r alib; do
        libname=$(basename "${alib}" .a)
        extract_dir=$(mktemp -d)
        pushd "${extract_dir}" >/dev/null
        "${AR}" -x "${alib}" 2>/dev/null || true
        for obj in *.o; do
            [ -f "$obj" ] || continue
            case "$obj" in
                main.o|vsyncapi.o|c1541-stubs.o|vsid-stubs.o) continue ;;
            esac
            # Skip headless video.o — provided by vice_jni.c
            if [[ "${alib}" == *headless* ]] && [ "$obj" = "video.o" ]; then continue; fi
            cp "$obj" "${OBJ_TMPDIR}/${CTR}_${libname}_${obj}"
            CTR=$((CTR+1))
        done
        popd >/dev/null
        rm -rf "${extract_dir}"
    done < <(find "${BUILD_DIR}/src" -name "*.a" \
        ! -path "*/c128/*" ! -path "*/scpu64/*" ! -path "*/c64dtv/*" \
        ! -path "*/cbm2/*" ! -path "*/pet/*"    ! -path "*/plus4/*" \
        ! -path "*/vic20/*" ! -path "*/viciisc/*" \
        | sort)

    OBJ_COUNT=$(find "${OBJ_TMPDIR}" -name "*.o" | wc -l)
    echo "    objects collected: ${OBJ_COUNT}"
    if [ "${OBJ_COUNT}" -eq 0 ]; then
        echo "ERROR: No object files collected — sub-library build may have failed" >&2
        rm -rf "${OBJ_TMPDIR}"
        exit 1
    fi
    "${AR}" -crs "${OUT}/libvice.a" "${OBJ_TMPDIR}"/*.o
    rm -rf "${OBJ_TMPDIR}"

    CONFIG_H=$(find "${BUILD_DIR}" -name "config.h" 2>/dev/null | head -1)
    if [ -z "${CONFIG_H}" ]; then
        echo "ERROR: config.h not found under ${BUILD_DIR}" >&2
        exit 1
    fi
    cp "${CONFIG_H}" "${OUT}/config.h"
    echo "  Built ${OUT}/libvice.a ($(du -sh "${OUT}/libvice.a" | cut -f1))"
    popd >/dev/null
}

build_abi "arm64-v8a" "aarch64-linux-android"
build_abi "x86_64"    "x86_64-linux-android"

echo ""
echo "=== VICE build complete ==="
