cmake_minimum_required(VERSION 3.22.1)

project("gaju-native")

set(LIBSODIUM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libsodium)
set(SODIUM_CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sodium-config)

# Define macros for libsodium on Android
add_definitions(-DCONFIG_H -D_GNU_SOURCE -D_POSIX_SOURCE)
add_definitions(-DHAVE_MMAP -DHAVE_MPROTECT -DHAVE_MADVISE)

# Target-specific optimizations
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
    add_definitions(-DHAVE_ARMCRYPTO -DHAVE_TI_MODE)
elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
    add_definitions(-DHAVE_TI_MODE)
endif()

add_library(gaju-native SHARED
        gaju-jni.c

        # Core & Runtime
        ${LIBSODIUM_DIR}/src/libsodium/sodium/core.c
        ${LIBSODIUM_DIR}/src/libsodium/sodium/runtime.c
        ${LIBSODIUM_DIR}/src/libsodium/sodium/utils.c
        ${LIBSODIUM_DIR}/src/libsodium/sodium/version.c
        ${LIBSODIUM_DIR}/src/libsodium/sodium/codecs.c

        # Random
        ${LIBSODIUM_DIR}/src/libsodium/randombytes/randombytes.c
        ${LIBSODIUM_DIR}/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c

        # Hash (SHA)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_hash/crypto_hash.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_hash/sha256/hash_sha256.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_hash/sha256/cp/hash_sha256_cp.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_hash/sha512/hash_sha512.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_hash/sha512/cp/hash_sha512_cp.c

        # Generic Hash (Blake2b)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_generichash/crypto_generichash.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_generichash/blake2b/generichash_blake2.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c

        # Sign (Ed25519)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_sign/crypto_sign.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_sign/ed25519/sign_ed25519.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_sign/ed25519/ref10/keypair.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_sign/ed25519/ref10/open.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_sign/ed25519/ref10/sign.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c

        # Scalarmult (Curve25519)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_scalarmult/crypto_scalarmult.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c

        # Core Crypto
        ${LIBSODIUM_DIR}/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_core/hchacha20/core_hchacha20.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_core/hsalsa20/core_hsalsa20.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_core/softaes/softaes.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_verify/verify.c

        # OneTimeAuth (Poly1305)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_onetimeauth/crypto_onetimeauth.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c

        # Stream (Chacha20/Salsa20)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_stream/crypto_stream.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_stream/chacha20/stream_chacha20.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_stream/salsa20/stream_salsa20.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_stream/xsalsa20/stream_xsalsa20.c

        # PWHash (Argon2)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/crypto_pwhash.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/argon2.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/argon2-core.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/blake2b-long.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c

        # AEAD (Aegis)
        ${LIBSODIUM_DIR}/src/libsodium/crypto_aead/aegis128l/aead_aegis128l.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_aead/aegis128l/aegis128l_soft.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_aead/aegis256/aead_aegis256.c
        ${LIBSODIUM_DIR}/src/libsodium/crypto_aead/aegis256/aegis256_soft.c
)

# Architecture specific optimizations
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
    target_sources(gaju-native PRIVATE
        ${LIBSODIUM_DIR}/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-neon.c
    )
endif()

target_include_directories(gaju-native PRIVATE
        ${SODIUM_CONFIG_DIR}
        ${LIBSODIUM_DIR}/src/libsodium/include
        ${LIBSODIUM_DIR}/src/libsodium/include/sodium
        ${LIBSODIUM_DIR}/src/libsodium/include/sodium/private
)

# Link log library for Android
find_library(log-lib log)
target_link_libraries(gaju-native ${log-lib})

# Target for IDE discovery (read-only reference)
add_custom_target(libsodium_all_headers SOURCES
    ${LIBSODIUM_DIR}/src/libsodium/include/sodium.h
)
