#!/usr/bin/env bash
set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
bundle="${1:-$repo_root/android/app/build/outputs/bundle/release/app-release.aab}"
minimum_alignment=$((16 * 1024))

if [[ ! -r "$bundle" ]]; then
	echo >&2 "Android bundle not found: $bundle"
	exit 1
fi

readelf_bin="${READELF:-}"
if [[ -z "$readelf_bin" ]]; then
	ndk_version="$(sed -n 's/^[[:space:]]*ndkVersion[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \
		"$repo_root/android/app/build.gradle.kts" | head -1)"
	sdk_dir="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-}}"
	if [[ -r "$repo_root/local.properties" ]]; then
		sdk_dir="$(sed -n 's/^sdk.dir=//p' "$repo_root/local.properties" | head -1)"
	fi
	ndk_readelf="$sdk_dir/ndk/$ndk_version/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-readelf"
	if [[ -x "$ndk_readelf" ]]; then
		readelf_bin="$ndk_readelf"
	else
		readelf_bin="$(command -v readelf || true)"
	fi
fi

if [[ -z "$readelf_bin" || ! -x "$readelf_bin" ]]; then
	echo >&2 "readelf was not found; set READELF to an executable path"
	exit 1
fi

temporary="$(mktemp -d)"
trap 'rm -rf "$temporary"' EXIT
unzip -q "$bundle" 'base/lib/*/*.so' -d "$temporary"

mapfile -d '' libraries < <(find "$temporary/base/lib" -type f -name '*.so' -print0 | sort -z)
if (( ${#libraries[@]} == 0 )); then
	echo >&2 "No native libraries found in Android bundle: $bundle"
	exit 1
fi

failed=false
for library in "${libraries[@]}"; do
	relative="${library#"$temporary/"}"
	while read -r alignment; do
		if [[ ! "$alignment" =~ ^0x[0-9a-fA-F]+$ ]]; then
			echo >&2 "$relative: invalid ELF LOAD alignment '$alignment'"
			failed=true
			continue
		fi
		if (( alignment < minimum_alignment )); then
			printf >&2 '%s: ELF LOAD alignment %s is below 0x4000\n' "$relative" "$alignment"
			failed=true
		fi
	done < <("$readelf_bin" -lW "$library" | awk '$1 == "LOAD" { print $NF }')
done

if [[ "$failed" == true ]]; then
	exit 1
fi

printf 'Android 16 kB ELF alignment verified for %d native libraries.\n' "${#libraries[@]}"
