package com.nsure.reactnative;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import javax.annotation.Nonnull;

/**
 * DEV-only fault-injection module. Lives in {@code src/debug/} so AGP
 * excludes it from release variants. Registered via reflection in
 * {@link NSureSDKPackage}.
 *
 * Callback contract matches iOS {@code NSureSDKCrashLab.crashWithKind:callback:}:
 * {@code callback(null)} → success; {@code callback(errorMessage)} → caught
 * crash, JS rejects with that string as the NSURE_ERROR message. Promise-style
 * was tried first but the legacy-interop bridge on RN 0.78 doesn't reliably
 * surface Promise rejections for reflectively-registered modules — the JS
 * side saw an immediate resolve instead of the expected reject, so the
 * Maestro {@code BRIDGE CAUGHT} assertion never matched. Callbacks bypass
 * that path entirely.
 *
 * MUST NOT install any uncaught-exception or signal handler — the nSure
 * native SDK owns those; its chained handler catches the bg-thread
 * Throwable raised by the {@code "jvmUncaughtBgThread"} kind.
 */
public class NSureSDKCrashLab extends ReactContextBaseJavaModule {

    static final String NAME = "NSureSDKCrashLab";

    public NSureSDKCrashLab(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Nonnull
    @Override
    public String getName() {
        return NAME;
    }

    @ReactMethod
    public void crashWithKind(String kind, Callback callback) {
        try {
            if ("jvmException".equals(kind)) {
                throw new RuntimeException("intentional jvm exception");
            } else if ("jvmUncaughtBgThread".equals(kind)) {
                // Escapes this call; chained handler in nSure SDK catches.
                new Thread(() -> { throw new RuntimeException("intentional bg thread crash"); }).start();
                callback.invoke((Object) null);
                return;
            } else if ("jniThrow".equals(kind)) {
                // UnsatisfiedLinkError is an Error subclass — exercises the
                // catch(Throwable) widening below.
                throw new UnsatisfiedLinkError("emulated JNI pending exception — no JNI in SDK today");
            } else if ("nativeSignal".equals(kind)) {
                // Hard process kill; host terminates and relaunches.
                android.os.Process.killProcess(android.os.Process.myPid());
                callback.invoke((Object) null);
                return;
            } else {
                callback.invoke("unknown crash kind: " + kind);
                return;
            }
        } catch (Throwable t) {
            // catch(Throwable), not catch(Exception): catches Error subclasses too.
            String message = t.getMessage();
            callback.invoke(message != null ? message : t.getClass().getSimpleName());
        }
    }
}
