import android.content.Context
import android.util.Base64
import android.util.Log
import com.google.android.gms.safetynet.SafetyNet
import com.google.android.gms.safetynet.SafetyNetApi
import com.google.android.gms.tasks.OnFailureListener
import com.google.android.gms.tasks.OnSuccessListener
import org.json.JSONObject
import java.io.IOException
import java.security.GeneralSecurityException
import java.security.SecureRandom
import java.util.Arrays

object SafetyNetCheck {

    private const val TAG = "SafetyNetCheck"

    fun checkSafetyNet(context: Context, apiKey: String, callback: (Boolean) -> Unit) {
        // Generate a nonce.  A good nonce is large, random, and used only once.
        val nonce = generateNonce()

        SafetyNet.getClient(context).attest(nonce, apiKey)
            .addOnSuccessListener { response ->
                // Success!  Now, *verify* the response.
                val jwsResult = response.jwsResult
                if (jwsResult != null) {
                    try {
                        val isSafe = SafetyNetResponseVerifier.verify(jwsResult)
                        Log.d(TAG, "SafetyNet verification result: $isSafe")
                        callback(isSafe) // Now passing a *verified* result.
                    } catch (e: Exception) {
                        Log.e(TAG, "Error verifying SafetyNet response: ${e.message}", e)
                        callback(false) // Treat verification errors as failures.
                    }
                } else {
                    Log.e(TAG, "SafetyNet jwsResult is null")
                    callback(false) // Null result is a failure.
                }
            }
            .addOnFailureListener { e ->
                Log.e(TAG, "SafetyNet attest API call failed: ${e.message}", e)
                callback(false) // API call failure.
            }
    }


    // Helper function to generate a nonce.
    private fun generateNonce(): ByteArray {
        val byteGenerator = SecureRandom()
        val nonce = ByteArray(32)
        byteGenerator.nextBytes(nonce)
        return nonce
    }
}



// Helper class to verify the SafetyNet response.
object SafetyNetResponseVerifier {

    private const val TAG = "SafetyNetVerifier"

    // This method *must* be implemented on a *backend server* for real security.
    // This is just a *simplified example* for demonstration purposes and is
    // *not* suitable for production without a backend check.
    @Throws(GeneralSecurityException::class, IOException::class)
    fun verify(jwsResult: String): Boolean {
        // 1. Parse the JWS: Split into header, payload, and signature.
        val parts = jwsResult.split(".")
        if (parts.size != 3) {
            Log.e(TAG, "Invalid JWS format")
            return false // Invalid JWS format
        }

        val header = parts[0]
        val payload = parts[1]
        val signature = parts[2]

        // 2. Decode the payload (it's Base64 encoded).
        val decodedPayload = Base64.decode(payload, Base64.DEFAULT)
        val payloadJson = JSONObject(String(decodedPayload))

        // 3. Check the ctsProfileMatch and basicIntegrity.
        val ctsProfileMatch = payloadJson.optBoolean("ctsProfileMatch", false)
        val basicIntegrity = payloadJson.optBoolean("basicIntegrity", false)

        Log.d(TAG, "ctsProfileMatch: $ctsProfileMatch, basicIntegrity: $basicIntegrity")

        // 4.  **CRITICAL:  In a real application, you *must* send the JWS to your
        //     backend server for verification.  The server should use the
        //     Google SafetyNet API (or a library that wraps it) to verify
        //     the signature and check the fields.  This prevents attackers
        //     from tampering with the response on the device.**
        //
        //    // Example (pseudo-code) of what the backend check would do:
        //    // GoogleCredential credential = ...;
        //    // SafetyNet safetyNet = new SafetyNet.Builder(httpTransport, jsonFactory)
        //    //     .setApplicationName("YourAppName")
        //    //     .setHttpRequestInitializer(credential)
        //    //     .build();
        //    // SafetyNetApi.VerifyJwsRequest request = safetyNet.safetynet().verifyJws(jwsResult);
        //    // SafetyNetApi.VerifyJwsResponse response = request.execute();
        //    // return response.isValidSignature() && response.getCtsProfileMatch() && response.getBasicIntegrity();

        // 5.  For this *example* (without a backend), we'll just check the fields.
        //     This is *NOT SECURE* for production!
        return ctsProfileMatch && basicIntegrity
    }
}