# Runtime keep rules consumed by applications that embed nav-core.
# Keep this file narrowly scoped: every rule is applied to the customer's complete R8 graph.

-keepattributes Signature,Exceptions
-keepattributes RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,AnnotationDefault

# Conventional JNI lookup requires the declaring class and native method names to remain stable.
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.NativeBridge {
    native <methods>;
}

# Offline routing progress is delivered by native code through name-based JNI lookup. This is a
# private JNI ABI, not a public SDK API: producer R8 and the customer's application R8 must retain
# both the model factory and the SAM method. Keeping only OfflineNavigationEngine is insufficient;
# R8 can otherwise erase the SAM method and scalar-replace/rename NativeRoutingProgress.
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.NativeRoutingProgress {
    public static ai.nextbillion.navigation.core.offline.NativeRoutingProgress fromNative(int, int, long, int, int);
}
-keep,allowoptimization,includedescriptorclasses interface ai.nextbillion.navigation.core.offline.NativeRoutingProgressListener {
    public void onNativeRoutingProgress(ai.nextbillion.navigation.core.offline.NativeRoutingProgress);
}
-keepclassmembers,allowoptimization class * implements ai.nextbillion.navigation.core.offline.NativeRoutingProgressListener {
    public void onNativeRoutingProgress(ai.nextbillion.navigation.core.offline.NativeRoutingProgress);
}

# Native errors are constructed through FindClass/GetMethodID rather than a Java reference.
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.NativeException {
    <init>(int, java.lang.String);
}

# The native off-route engine is selected through the navigation engine factory and invoked through
# virtual overrides. `-keepclasseswithmembernames` is insufficient here: a consuming application's
# whole-program R8 pass may prove only the constructor/close path reachable and remove the decision
# overrides together with their native callees. Keep these two narrowly scoped runtime classes in
# both the producer AAR pass and the consuming application pass so C++ decisions cannot silently
# degrade to the inherited Java implementation after minification.
-keep class ai.nextbillion.navigation.core.offroute.NativeOffRouteBridge {
    *;
}
-keep class ai.nextbillion.navigation.core.offroute.OffRouteDecisionEngineNative {
    *;
}

# Region download callbacks and catalog models are also reached through name-based JNI lookup.
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.region.RegionDownloadProgress {
    public static ai.nextbillion.navigation.core.offline.region.RegionDownloadProgress fromNative(long, int, int, int, int);
}
-keep,allowoptimization,includedescriptorclasses interface ai.nextbillion.navigation.core.offline.region.RegionDownloadProgressListener {
    public void onProgress(ai.nextbillion.navigation.core.offline.region.RegionDownloadProgress);
}
-keepclassmembers,allowoptimization class * implements ai.nextbillion.navigation.core.offline.region.RegionDownloadProgressListener {
    public void onProgress(ai.nextbillion.navigation.core.offline.region.RegionDownloadProgress);
}
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.region.OfflineRegionLeaf {
    public <init>(...);
}
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.region.OfflineRegionCatalog {
    public static ai.nextbillion.navigation.core.offline.region.OfflineRegionCatalog buildFromNative(...);
}
-keep,allowoptimization,includedescriptorclasses class ai.nextbillion.navigation.core.offline.region.OfflineRegionCountriesResult {
    public static ai.nextbillion.navigation.core.offline.region.OfflineRegionCountriesResult fromNative(...);
}

# Retrofit creates only these SDK-owned service interfaces through reflection. nav-core is
# producer-minified before the consuming application runs its own R8 pass. Keep the interface names
# stable in the producer AAR so these packaged source-name rules still match during that second pass;
# otherwise R8 can discard Call<T>'s Signature and Retrofit rejects the service at runtime.
# Retrofit 2.9's packaged rules predate R8 full mode. Keep the raw return type so the consuming
# application's R8 pass retains each service method's Call<T> Signature attribute.
-keep,allowobfuscation,allowshrinking interface retrofit2.Call

-keep,allowoptimization,allowshrinking interface ai.nextbillion.navigation.core.routefetcher.NBNavigationAPI
-keep,allowoptimization,allowshrinking interface ai.nextbillion.navigation.core.offroute.SnapToRoadAPI
-keepclassmembers,allowobfuscation interface ai.nextbillion.navigation.core.routefetcher.NBNavigationAPI {
    @retrofit2.http.* <methods>;
}
-keepclassmembers,allowobfuscation interface ai.nextbillion.navigation.core.offroute.SnapToRoadAPI {
    @retrofit2.http.* <methods>;
}

# Gson 2.9 does not package R8 full-mode rules. TypeToken reads its type argument from the generic
# superclass Signature, so keep both TypeToken and SDK/customer anonymous subclasses during the
# consuming application's R8 pass.
-if class com.google.gson.reflect.TypeToken
-keep,allowobfuscation class com.google.gson.reflect.TypeToken
-keep,allowobfuscation class * extends com.google.gson.reflect.TypeToken

# Preserve only SDK-owned serialized fields; model class names and unrelated customer models remain
# optimizable.
-keepclassmembers,allowobfuscation class ai.nextbillion.navigation.** {
    @com.google.gson.annotations.SerializedName <fields>;
}
-keepclassmembers,allowobfuscation class ai.nextbillion.kits.** {
    @com.google.gson.annotations.SerializedName <fields>;
}

# Android and Java serialization hooks used by SDK-owned state/model classes.
-keepclassmembers class ai.nextbillion.** implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator CREATOR;
}
-keepnames class ai.nextbillion.** implements java.io.Serializable
-keepclassmembers class ai.nextbillion.** implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

-keepclassmembers enum ai.nextbillion.** {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# Compile-only AutoValue annotations and optional desktop-only types are absent on Android.
-dontwarn com.google.auto.value.**
-dontwarn java.awt.Color
-dontwarn java.lang.invoke.StringConcatFactory
-dontwarn com.sun.xml.internal.ws.spi.db.BindingContextFactory

# OpenTelemetry's exporter-common contains an optional JSON serializer. OTLP/OkHttp does not put
# Jackson on the Android runtime path; suppress only the two optional references reported by R8.
-dontwarn com.fasterxml.jackson.core.JsonFactory
-dontwarn com.fasterxml.jackson.core.JsonGenerator
