#!/bin/bash

# Check ELF .so alignment in APK for 16KB page size compatibility
# Files must have PT_LOAD segments aligned to 16384 bytes (0x4000)

APK="${1:-/Users/mohamedmekawy/Documents/Work/HMG_Patient_App_New/android/app/release/app-release.apk}"
LLVM_READELF="/Users/mohamedmekawy/Library/Android/sdk/ndk/28.2.13676358/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf"
EXTRACT_DIR="/tmp/apk_alignment_check"
REQUIRED_ALIGNMENT=16384  # 16 KB

echo "========================================"
echo "  ELF Alignment Check for 16KB Page Size"
echo "========================================"
echo "APK: $APK"
echo ""

if [ ! -f "$APK" ]; then
    echo "ERROR: APK not found at $APK"
    exit 1
fi

# Clean and extract APK
rm -rf "$EXTRACT_DIR"
mkdir -p "$EXTRACT_DIR"
unzip -q "$APK" -d "$EXTRACT_DIR"

# Find all .so files
SO_FILES=$(find "$EXTRACT_DIR" -name "*.so")

if [ -z "$SO_FILES" ]; then
    echo "No .so files found in APK."
    exit 0
fi

FAILED=()
PASSED=()

for SO in $SO_FILES; do
    RELATIVE="${SO#$EXTRACT_DIR/}"

    # Check if it's a valid ELF
    MAGIC=$(xxd -l 4 "$SO" 2>/dev/null | head -1)
    if [[ "$MAGIC" != *"7f45 4c46"* ]]; then
        continue
    fi

    # Use llvm-readelf from NDK
    READELF_OUTPUT=$("$LLVM_READELF" -l "$SO" 2>/dev/null)

    if [ -z "$READELF_OUTPUT" ]; then
        echo "⚠️  SKIP (readelf unavailable): $RELATIVE"
        continue
    fi

    # Extract LOAD segment alignments
    MISALIGNED=false
    while IFS= read -r line; do
        if [[ "$line" == *"LOAD"* ]]; then
            # Get the last field (Align column)
            ALIGN=$(echo "$line" | awk '{print $NF}')
            # Convert hex to decimal if needed
            if [[ "$ALIGN" == 0x* ]]; then
                ALIGN_DEC=$((ALIGN))
            else
                ALIGN_DEC=$ALIGN
            fi

            if [[ "$ALIGN_DEC" =~ ^[0-9]+$ ]]; then
                if [ "$ALIGN_DEC" -lt "$REQUIRED_ALIGNMENT" ] && [ "$ALIGN_DEC" -gt 0 ]; then
                    MISALIGNED=true
                    ALIGN_KB=$((ALIGN_DEC / 1024))
                    echo "❌ FAIL (${ALIGN_KB}KB aligned): $RELATIVE"
                    break
                fi
            fi
        fi
    done <<< "$READELF_OUTPUT"

    if [ "$MISALIGNED" = false ]; then
        ALIGN_LINE=$(echo "$READELF_OUTPUT" | grep "LOAD" | head -1 | awk '{print $NF}')
        echo "✅ PASS ($ALIGN_LINE aligned): $RELATIVE"
        PASSED+=("$RELATIVE")
    else
        FAILED+=("$RELATIVE")
    fi
done

echo ""
echo "========================================"
echo "SUMMARY"
echo "========================================"
echo "✅ Passed (16KB+ aligned): ${#PASSED[@]}"
echo "❌ Failed (< 16KB aligned): ${#FAILED[@]}"

if [ ${#FAILED[@]} -gt 0 ]; then
    echo ""
    echo "The following .so files are NOT 16KB page aligned:"
    for f in "${FAILED[@]}"; do
        echo "  - $f"
    done
    echo ""
    echo "These files will cause issues on Android 15+ devices with 16KB page size."
else
    echo ""
    echo "All .so files are 16KB page aligned. ✅"
fi

# Cleanup
rm -rf "$EXTRACT_DIR"

