package info.nightscout.utils;

import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;

import java.util.Date;

/**
 * Created by jamorham on 21/02/2018.
 *
 * Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way
 * to disable them and make calls from a potentially invalid singleton reference. This wrapper
 * emulates the methods but ignores the request if the instance is null or invalid.
 *
 */

public class FabricPrivacy {

    private static final String TAG = "FabricPrivacy";
    private static volatile FabricPrivacy instance;


    public static FabricPrivacy getInstance() {
        if (instance == null) {
            initSelf();
        }
        return instance;
    }

    private static synchronized void initSelf() {
        if (instance == null) {
            instance = new FabricPrivacy();
        }
    }

    // Crashlytics logException
    public static void logException(Throwable throwable) {
        try {
            final Crashlytics crashlytics = Crashlytics.getInstance();
            crashlytics.core.logException(throwable);
        } catch (NullPointerException | IllegalStateException e) {
            android.util.Log.d(TAG, "Ignoring opted out non-initialized log: " + throwable);
        }
    }

    // Crashlytics log
    public static void log(String msg) {
        try {
            final Crashlytics crashlytics = Crashlytics.getInstance();
            crashlytics.core.log(msg);
        } catch (NullPointerException | IllegalStateException e) {
            android.util.Log.d(TAG, "Ignoring opted out non-initialized log: " + msg);
        }
    }

    // Crashlytics log
    public static void log(int priority, String tag, String msg) {
        try {
            final Crashlytics crashlytics = Crashlytics.getInstance();
            crashlytics.core.log(priority, tag, msg);
        } catch (NullPointerException | IllegalStateException e) {
            android.util.Log.d(TAG, "Ignoring opted out non-initialized log: " + msg);
        }
    }

    public static boolean fabricEnabled() {
        return SP.getBoolean("enable_fabric", true);
    }

    // Answers logCustom
    public void logCustom(CustomEvent event) {
        try {
            final Answers answers = Answers.getInstance();
            if (fabricEnabled()) {
                answers.logCustom(event);
            } else {
                android.util.Log.d(TAG, "Ignoring recently opted-out event: " + event.toString());
            }
        } catch (NullPointerException | IllegalStateException e) {
            android.util.Log.d(TAG, "Ignoring opted-out non-initialized event: " + event.toString());
        }
    }

    public static void uploadDailyStats() {
        if (!fabricEnabled()) return;

        long lastUploadDay = SP.getLong(MainApp.gs(R.string.key_plugin_stats_report_timestamp), 0L);

        Date date = new Date();
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        long today = date.getTime() - date.getTime() % 1000;

        if (today > lastUploadDay) {
            uploadAppUsageType();
            uploadPluginStats();

            SP.putLong(MainApp.gs(R.string.key_plugin_stats_report_timestamp), today);
        }
    }

    private static void uploadPluginStats() {
        CustomEvent pluginStats = new CustomEvent("PluginStats");
        pluginStats.putCustomAttribute("version", BuildConfig.VERSION);
        for (PluginBase plugin : MainApp.getPluginsList()) {
            if (plugin.isEnabled(plugin.getType()) && !plugin.pluginDescription.alwaysEnabled) {
                pluginStats.putCustomAttribute(plugin.getClass().getSimpleName(), "enabled");
            }
        }

        getInstance().logCustom(pluginStats);
    }

    private static void uploadAppUsageType() {
        CustomEvent type = new CustomEvent("AppUsageType");
        if (Config.NSCLIENT)
            type.putCustomAttribute("type", "NSClient");
        else if (Config.PUMPCONTROL)
            type.putCustomAttribute("type", "PumpControl");
        else if (MainApp.getConstraintChecker().isClosedLoopAllowed().value())
            type.putCustomAttribute("type", "ClosedLoop");
        else
            type.putCustomAttribute("type", "OpenLoop");

        getInstance().logCustom(type);
    }

}

@@ -169,16 +169,17 @@
 mEvent;%0A
+%0A
 import i
@@ -465,16 +465,20 @@
 2018.%0A *
+ %3Cp%3E
 %0A * Some
@@ -752,11 +752,8 @@
 id.%0A
- *%0A
  */%0A
@@ -3828,46 +3828,8 @@
 if (
-plugin.isEnabled(plugin.getType()) && 
 !plu
@@ -3863,24 +3863,203 @@
 sEnabled) %7B%0A
+                if (plugin.isEnabled(plugin.getType()))%0A                    pluginStats.putCustomAttribute(plugin.getClass().getSimpleName(), %22enabled%22);%0A                else%0A    
             
@@ -4121,34 +4121,35 @@
 tSimpleName(), %22
-en
+dis
 abled%22);%0A       

update PluginStats