# =============================================================================
# Koard SDK consumer ProGuard rules
#
# These rules are applied to the consuming app's R8/ProGuard pass. Their job is
# to keep classes/members that the Koard SDK (and its shaded dependencies) need
# at runtime via reflection.
#
# Shaded dependencies live under `com.koardlabs.*` (see packageRelocations in
# koard-android/build.gradle.kts), so all -keep rules here target the relocated
# packages rather than upstream names like okhttp3.* / retrofit2.*.
# =============================================================================

# --- Koard public API + DTOs (serialized by name through kotlinx.serialization)
-keep class com.koardlabs.merchant.sdk.** { *; }
-keepclassmembers class com.koardlabs.merchant.sdk.** { *; }

# --- Visa KiC bundled classes ---------------------------------------------------
-keep class com.visa.** { *; }
-dontwarn com.visa.**

# --- Shaded OkHttp / Okio -------------------------------------------------------
-dontwarn com.koardlabs.okhttp3.**
-dontwarn com.koardlabs.okio.**
-keep class com.koardlabs.okhttp3.internal.** { *; }
-keep class com.koardlabs.okio.** { *; }

# OkHttp pulls in optional Conscrypt / BouncyCastle / OpenJSSE TLS providers via
# Class.forName(...) on string literals. Those strings are NOT relocated by the
# shading step, so they still reference upstream package names. We don't bundle
# any of these providers - OkHttp falls back to the platform default - so
# suppress the missing-class warnings R8 would otherwise emit.
-dontwarn org.conscrypt.**
-dontwarn org.openjsse.**
-dontwarn org.bouncycastle.**

# AndroidX Security's Tink dependency references optional static-analysis
# annotations. They are not needed at runtime and are absent in lean host apps.
-dontwarn com.google.errorprone.annotations.CanIgnoreReturnValue
-dontwarn com.google.errorprone.annotations.CheckReturnValue
-dontwarn com.google.errorprone.annotations.Immutable
-dontwarn com.google.errorprone.annotations.RestrictedApi

# --- Shaded Retrofit ------------------------------------------------------------
-dontwarn com.koardlabs.retrofit2.**
-keepattributes Signature, InnerClasses, EnclosingMethod
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
-keepattributes AnnotationDefault
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @com.koardlabs.retrofit2.http.* <methods>;
}

# R8 full mode preserves generic signatures only when the participating types
# are kept. Retrofit reads Continuation<Response<T>> before sending a suspend
# request; stripping these signatures breaks login before any HTTP traffic.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-keep,allowobfuscation,allowshrinking class com.koardlabs.retrofit2.Response

# Retrofit creates service implementations with java.lang.reflect.Proxy.
-if interface * { @com.koardlabs.retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
-if interface * { @com.koardlabs.retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
-if interface * { @com.koardlabs.retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>

# --- Shaded kotlinx.serialization ----------------------------------------------
-dontwarn com.koardlabs.kotlinx.serialization.**
# Keep generated $serializer companions on Koard's @Serializable types.
-if @com.koardlabs.kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
    static <1>$Companion Companion;
}
-if @com.koardlabs.kotlinx.serialization.Serializable class ** {
    static **$* *;
}
-keepclassmembers class <2>$<3> {
    com.koardlabs.kotlinx.serialization.KSerializer serializer(...);
}

# --- Kotlin metadata (needed for reflection on shaded classes) -----------------
-keepattributes *Annotation*
-keep class kotlin.Metadata { *; }

# Bundled dependency consumer rules
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @com.koardlabs.retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn com.koardlabs.retrofit2.KotlinExtensions
-dontwarn com.koardlabs.retrofit2.KotlinExtensions$*

# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @com.koardlabs.retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>

# Keep inherited services.
-if interface * { @com.koardlabs.retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>

# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

# R8 full mode strips generic signatures from return types if not kept.
-if interface * { @com.koardlabs.retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>

# With R8 full mode generic signatures are stripped for classes that are not kept.
-keep,allowobfuscation,allowshrinking class com.koardlabs.retrofit2.Response


# Most of volatile fields are updated with AtomicFU and should not be mangled/removed
-keepclassmembers class com.koardlabs.ktor.** {
    volatile <fields>;
}

-keepclassmembernames class com.koardlabs.ktor.** {
    volatile <fields>;
}

# client engines are loaded using ServiceLoader so we need to keep them
-keep class com.koardlabs.ktor.client.engine.** implements com.koardlabs.ktor.client.HttpClientEngineContainer



# Keep `Companion` object fields of serializable classes.
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
-if @com.koardlabs.kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
    static <1>$* Companion;
}

# Keep names for named companion object from obfuscation
# Names of a class and of a field are important in lookup of named companion in runtime
-keepnames @com.koardlabs.kotlinx.serialization.internal.NamedCompanion class *
-if @com.koardlabs.kotlinx.serialization.internal.NamedCompanion class *
-keepclassmembernames class * {
    static <1> *;
}

# Keep `serializer()` on companion objects (both default and named) of serializable classes.
-if @com.koardlabs.kotlinx.serialization.Serializable class ** {
    static **$* *;
}
-keepclassmembers class <2>$<3> {
    com.koardlabs.kotlinx.serialization.KSerializer serializer(...);
}

# Keep `INSTANCE.serializer()` of serializable objects.
-if @com.koardlabs.kotlinx.serialization.Serializable class ** {
    public static ** INSTANCE;
}
-keepclassmembers class <1> {
    public static <1> INSTANCE;
    com.koardlabs.kotlinx.serialization.KSerializer serializer(...);
}

# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault

# Don't print notes about potential mistakes or omissions in the configuration for kotlinx-serialization classes
# See also https://github.com/Kotlin/kotlinx.serialization/issues/1900
-dontnote com.koardlabs.kotlinx.serialization.**

# Serialization core uses `java.lang.ClassValue` for caching inside these specified classes.
# If there is no `java.lang.ClassValue` (for example, in Android), then R8/ProGuard will print a warning.
# However, since in this case they will not be used, we can disable these warnings
-dontwarn com.koardlabs.kotlinx.serialization.internal.ClassValueReferences

# disable optimisation for descriptor field because in some versions of ProGuard, optimization generates incorrect bytecode that causes a verification error
# see https://github.com/Kotlin/kotlinx.serialization/issues/2719
-keepclassmembers public class **$$serializer {
    private ** descriptor;
}

