package com.goon.mobile

import android.content.pm.PackageManager
import android.content.pm.Signature
import android.os.Build
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import java.security.MessageDigest

/**
 * Native bridge that returns SHA-256 (hex) of the APK's signing certificate.
 *
 * Mobile sends this hash in the X-App-Signature header on every request.
 * Backend compares against ALLOWED_APP_SIG_HASH. Re-packaging the APK with
 * a different keystore (e.g. someone unzipping, modifying JS, re-signing
 * with a debug keystore) yields a different hash and is rejected with 403.
 *
 * Caveat: a sufficiently motivated attacker on a rooted device can hook
 * PackageManager via Frida/Xposed and return the original hash. This is
 * a speed bump, not a wall.
 */
class AntiTamperModule(reactContext: ReactApplicationContext) :
    ReactContextBaseJavaModule(reactContext) {

    override fun getName(): String = "AntiTamper"

    @ReactMethod
    fun getSignatureHash(promise: Promise) {
        try {
            val ctx = reactApplicationContext
            val pkgName = ctx.packageName
            val pm = ctx.packageManager

            val signatures: Array<Signature>? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                val info = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNING_CERTIFICATES)
                val si = info.signingInfo
                if (si == null) {
                    null
                } else if (si.hasMultipleSigners()) {
                    si.apkContentsSigners
                } else {
                    si.signingCertificateHistory
                }
            } else {
                @Suppress("DEPRECATION")
                pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES).signatures
            }

            if (signatures == null || signatures.isEmpty()) {
                promise.reject("ERR_NO_SIG", "no signatures on package $pkgName")
                return
            }

            val md = MessageDigest.getInstance("SHA-256")
            val hash = md.digest(signatures[0].toByteArray())
            val hex = hash.joinToString("") { "%02x".format(it) }
            promise.resolve(hex)
        } catch (e: Exception) {
            promise.reject("ERR_HASH", e.message ?: "unknown", e)
        }
    }
}
