package com.tasapp.capacitor;

import android.Manifest;

import com.getcapacitor.JSArray;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import com.tasapp.android.crashlytics.CrashlyticsService;

import org.json.JSONException;
import org.json.JSONObject;

@CapacitorPlugin(
        name = "TasFirebaseCrashlytics",
        permissions = {
                @Permission(strings = { Manifest.permission.ACCESS_NETWORK_STATE }, alias = "network"),
                @Permission(strings = { Manifest.permission.INTERNET }, alias = "internet"),
                @Permission(strings = { Manifest.permission.WAKE_LOCK }, alias = "wakelock")
        }
)
public class TasFirebaseCrashlyticsPlugin extends Plugin {

    public static final String ERROR_MESSAGE_MISSING = "message must be provided.";
    public static final String ERROR_ENABLED_MISSING = "enabled must be provided.";

    @Override
    public void load() {
        CrashlyticsService.getInstance();
    }

    @PluginMethod
    public void crash(PluginCall call) {
        String message = call.getString("message");
        if (message == null) {
            call.reject(ERROR_MESSAGE_MISSING);
            return;
        }
        call.resolve();
        CrashlyticsService.getInstance().crash(message);
    }

    @PluginMethod
    public void addLogMessage(PluginCall call) {
        String message = call.getString("message");
        if (message == null) {
            call.reject(ERROR_MESSAGE_MISSING);
            return;
        }
        CrashlyticsService.getInstance().addLogMessage(message);
        call.resolve();
    }

    @PluginMethod
    public void setEnabled(PluginCall call) {
        Boolean enabled = call.getBoolean("enabled");
        if (enabled == null) {
            call.reject(ERROR_ENABLED_MISSING);
            return;
        }
        CrashlyticsService.getInstance().setEnabled(enabled);
        call.resolve();
    }

    @PluginMethod
    public void recordException(PluginCall call) {
        String message = call.getString("message");
        if (message == null) {
            call.reject(ERROR_MESSAGE_MISSING);
            return;
        }

        JSArray stacktrace = call.getArray("stacktrace", null);
        CrashlyticsService.getInstance().recordException(message, handleStacktrace(stacktrace));
        call.resolve();
    }

    private StackTraceElement[] handleStacktrace(JSArray stackTrace) {
        if (stackTrace == null) {
            return null;
        }

        StackTraceElement[] trace = new StackTraceElement[stackTrace.length()];
        int pos = 0;
        for (int i = 0; i < stackTrace.length(); i++) {
            JSONObject elem = null;
            try {
                elem = stackTrace.getJSONObject(i);
                trace[pos] =
                        new StackTraceElement(
                                "",
                                elem.optString("functionName", "(anonymous function)"),
                                elem.optString("fileName", "(unknown file)"),
                                elem.optInt("lineNumber", -1)
                        );
                pos++;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        return trace;
    }
}
