#!/bin/bash
# NIP ARM64 Static Build Script using Zig
# Builds a fully static ARM64 binary using Zig as C compiler with musl
set -e

echo "🚀 Building NIP for ARM64 (aarch64-linux-musl) using Zig"
echo "========================================================="
echo ""

# Check dependencies
if ! command -v nim &> /dev/null; then
    echo "❌ Error: Nim compiler not found"
    exit 1
fi

if ! command -v zig &> /dev/null; then
    echo "❌ Error: Zig compiler not found"
    exit 1
fi

echo "📋 Nim version: $(nim --version | head -1)"
echo "📋 Zig version: $(zig version)"
echo ""

# Create Zig wrapper that shadows aarch64-linux-gnu-gcc
ZIG_WRAPPER_DIR="/tmp/nip-zig-wrappers-arm64"
rm -rf "$ZIG_WRAPPER_DIR"
mkdir -p "$ZIG_WRAPPER_DIR"

# Create a wrapper named exactly "aarch64-linux-gnu-gcc" that calls zig cc
# This shadows the system's aarch64-linux-gnu-gcc when prepended to PATH
# Filters out x86-specific compile flags AND problematic linker flags
cat > "$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" << 'WRAPPER'
#!/bin/bash
# Zig CC wrapper for ARM64 cross-compilation
# Shadows system's aarch64-linux-gnu-gcc and filters incompatible flags

FILTERED_ARGS=()
echo "Wrapper called with:" >> /tmp/wrapper.log
printf "'%s' " "$@" >> /tmp/wrapper.log
echo "" >> /tmp/wrapper.log

for arg in "$@"; do
    case "$arg" in
        # Skip x86-specific compile flags
        -mpclmul|-maes|-msse*|-mavx*|-mno-80387|-fcf-protection|-fstack-clash-protection)
            ;;
        -march=x86*|-march=native)
            ;;
        -mtune=haswell|-mtune=skylake|-mtune=generic)
            ;;
        -Wp,-D_FORTIFY_SOURCE=*)
            ;;
        -flto)
            # LTO can cause issues with zig cross-compile
            ;;
        # Skip dynamic library flags that don't work with musl static
        -ldl)
            # musl's libc.a includes dl* functions, no separate libdl needed
            ;;
        # Filter all march/mtune flags to avoid zig cc conflicts
        -m64|-m32|-march=*|-mtune=*|-mcpu=*|-Xclang*|-target-feature*)
            # skip host-specific flags
            ;;
        *)
            FILTERED_ARGS+=("$arg")
            ;;
    esac
done

exec zig cc -target aarch64-linux-musl "${FILTERED_ARGS[@]}"
WRAPPER
chmod +x "$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc"

echo "✅ Created Zig wrapper at $ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc"
echo ""

# Clean previous builds and cache
echo "🧹 Cleaning previous ARM64 builds and Nim cache..."
rm -f nip-arm64 nip_arm64 nip-arm64-musl
rm -rf ~/.cache/nim/nip_*
rm -rf /tmp/nip-arm64-cache
echo ""

# Prepend our wrapper to PATH
export PATH="$ZIG_WRAPPER_DIR:$PATH"

# Verify our wrapper is first in PATH
FOUND_GCC=$(which aarch64-linux-gnu-gcc)
echo "🔍 Using gcc wrapper: $FOUND_GCC"
echo ""

# Compile statically
echo "🔨 Building optimized ARM64 static binary..."
echo "   Target: aarch64-linux-musl (static via Zig)"
echo "   This may take a few minutes..."

nim c \
    --cpu:arm64 \
    --os:linux \
    --cc:gcc \
    --gcc.exe:"$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" \
    --gcc.linkerexe:"$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" \
    --passC:"-O2" \
    --passC:"-w" \
    --passL:-static \
    --passL:-s \
    -d:release \
    -d:danger \
    -d:nimcrypto_disable_neon \
    -d:nimcrypto_no_asm \
    -d:nimcrypto_sysrand \
    --opt:size \
    --mm:orc \
    --threads:on \
    --nimcache:/tmp/nip-arm64-cache \
    --skipProjCfg \
    --out:nip-arm64 \
    src/nip.nim 2>&1 | tee /tmp/nip-arm64-build.log

if [ ! -f "nip-arm64" ]; then
    echo ""
    echo "❌ Build failed! Check /tmp/nip-arm64-build.log for details"
    echo "Last 20 lines of error:"
    tail -20 /tmp/nip-arm64-build.log
    exit 1
fi

echo ""
echo "✅ Build successful!"
echo ""

# Show binary info
echo "📊 Binary Information:"
ls -lh nip-arm64
echo ""

echo "🔍 File details:"
file nip-arm64
echo ""

# Verify it's ARM64
if file nip-arm64 | grep -q "ARM aarch64"; then
    echo "✅ Verified: Binary is ARM64 aarch64"
else
    echo "⚠️  Binary may not be ARM64 - check file output above"
fi
echo ""

# Verify static linking with readelf
echo "🔍 Verifying static linking..."
if readelf -d nip-arm64 2>/dev/null | grep -q "NEEDED"; then
    echo "⚠️  Binary has dynamic dependencies:"
    readelf -d nip-arm64 2>/dev/null | grep NEEDED
else
    echo "✅ No dynamic dependencies found (fully static)"
fi
echo ""

# Test with QEMU if available
echo "🧪 Testing binary with QEMU user-mode emulation..."
if command -v qemu-aarch64 &> /dev/null; then
    if timeout 10 qemu-aarch64 ./nip-arm64 --version 2>&1; then
        echo "✅ Binary works under QEMU aarch64 emulation"
    else
        echo "⚠️  Binary may need additional setup"
    fi
else
    echo "ℹ️  QEMU aarch64 user-mode not available"
fi
echo ""

# Create output directory
OUTPUT_DIR="build/arm64"
mkdir -p "$OUTPUT_DIR"
cp nip-arm64 "$OUTPUT_DIR/nip"
chmod +x "$OUTPUT_DIR/nip"

echo "🎉 ARM64 build complete!"
echo ""
echo "📋 Build Summary:"
echo "   Binary: nip-arm64"
echo "   Target: aarch64-linux-musl (static)"
echo "   Size: $(ls -lh nip-arm64 | awk '{print $5}')"
echo "   Output: $OUTPUT_DIR/nip"
echo ""
echo "📦 Ready for NexBox integration!"
