package li.doerf.hacked;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.multidex.MultiDexApplication;

import com.google.android.gms.security.ProviderInstaller;
import com.google.firebase.analytics.FirebaseAnalytics;

import java.util.List;

import li.doerf.hacked.db.AppDatabase;
import li.doerf.hacked.db.daos.AccountDao;
import li.doerf.hacked.db.daos.BreachDao;
import li.doerf.hacked.db.entities.Account;
import li.doerf.hacked.db.entities.Breach;
import li.doerf.hacked.utils.BackgroundTaskHelper;
import li.doerf.hacked.utils.SynchronizationHelper;

/**
 * Created by moo on 25.05.17.
 */

public class HackedApplication extends MultiDexApplication implements LifecycleObserver, DefaultLifecycleObserver {
    private static final String TAG = "HackedApplication";
    private static final String PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE = "PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE";
    private FirebaseAnalytics firebaseAnalytics;

    @Override
    public void onCreate() {
        super.onCreate();
        enableTls12ForAndroidApi19AndBelow();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
        firebaseAnalytics = FirebaseAnalytics.getInstance(this);
        migrateBackgroundCheckService();
        migrateNumBreaches();
    }

    private void enableTls12ForAndroidApi19AndBelow() {
        ProviderInstaller.installIfNeededAsync(this, new ProviderInstaller.ProviderInstallListener() {
            @Override
            public void onProviderInstalled() {
            }
            @Override
            public void onProviderInstallFailed(int i, Intent intent) {
                Log.i(TAG, "Provider install failed (" + i + ") : SSL Problems may occurs");
            }
        });
    }

    public synchronized void trackView(String name) {
        if ( runsInTestlab() ) return;
        Bundle bundle = new Bundle();
        bundle.putString(FirebaseAnalytics.Param.ITEM_ID, name);
        bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, "View");
        firebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM, bundle);
    }

    public synchronized void trackCustomEvent(CustomEvent eventName) {
        if ( runsInTestlab() ) return;
        Bundle bundle = new Bundle();
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "Function");
        firebaseAnalytics.logEvent(eventName.name(), bundle);
    }

    private boolean runsInTestlab() {
        String testLabSetting = Settings.System.getString(getContentResolver(), "firebase.test.lab");
        return "true".equals(testLabSetting);
    }

    public void migrateBackgroundCheckService() {
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        boolean done = settings.getBoolean(PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE, false);

        if (done) {
            return;
        }

        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(getString(R.string.pref_key_sync_enable), true);
        editor.apply();

        Log.i(TAG, "migrating background check service to workmanager");

        SynchronizationHelper.scheduleSync(getApplicationContext());

        // update preference
        editor.putBoolean(PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE, true);
        editor.apply();
        Log.d(TAG, "done");
    }

    private void migrateNumBreaches() {
        Log.i(TAG, "checking if accounts with numBreaches null must be migrated");
        AccountDao accountDao = AppDatabase.get(getApplicationContext()).getAccountDao();
        BreachDao breachDao = AppDatabase.get(getApplicationContext()).getBreachDao();

        new BackgroundTaskHelper<Boolean>().runInBackgroundAndConsumeOnMain(
                () -> {
                    List<Account> accounts = accountDao.getAllWithNumBreachesNull();
                    Log.d(TAG, accounts.size() + " accounts to migrate");

                    for (Account account : accounts) {
                        List<Breach> breaches = breachDao.findByAccount(account.getId());
                        Long numUnAck = breachDao.countUnacknowledged(account.getId());
                        Long numAck = breaches.size() - numUnAck;
                        account.setNumBreaches(breaches.size());
                        account.setNumAcknowledgedBreaches(numAck.intValue());
                        accountDao.update(account);
                        Log.i(TAG, "updated account: numBreaches=" + account.getNumBreaches() + " numAcknowledgedBreaches=" + account.getNumAcknowledgedBreaches());
                    }

                    return true;
                },
                (b) -> {
                    // do nothing
                });
    }

    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        Log.d(TAG, "application opened");
        Bundle bundle = new Bundle();
        firebaseAnalytics.logEvent(FirebaseAnalytics.Event.APP_OPEN, bundle);
    }

}

@@ -69,104 +69,17 @@
 oid.
-content.SharedPreferences;%0Aimport android.os.Bundle;%0Aimport android.preference.PreferenceManager
+os.Bundle
 ;%0Aim
@@ -526,347 +526,8 @@
 s;%0A%0A
-import java.util.List;%0A%0Aimport li.doerf.hacked.db.AppDatabase;%0Aimport li.doerf.hacked.db.daos.AccountDao;%0Aimport li.doerf.hacked.db.daos.BreachDao;%0Aimport li.doerf.hacked.db.entities.Account;%0Aimport li.doerf.hacked.db.entities.Breach;%0Aimport li.doerf.hacked.utils.BackgroundTaskHelper;%0Aimport li.doerf.hacked.utils.SynchronizationHelper;%0A%0A
 /**%0A
@@ -741,157 +741,8 @@
 n%22;%0A
-    private static final String PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE = %22PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE%22;%0A
     
@@ -1041,79 +1041,8 @@
 s);%0A
-        migrateBackgroundCheckService();%0A        migrateNumBreaches();%0A
     
@@ -2291,24 +2291,24 @@
 test.lab%22);%0A
+
         retu
@@ -2352,2191 +2352,8 @@
  %7D%0A%0A
-    public void migrateBackgroundCheckService() %7B%0A        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());%0A        boolean done = settings.getBoolean(PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE, false);%0A%0A        if (done) %7B%0A            return;%0A        %7D%0A%0A        SharedPreferences.Editor editor = settings.edit();%0A        editor.putBoolean(getString(R.string.pref_key_sync_enable), true);%0A        editor.apply();%0A%0A        Log.i(TAG, %22migrating background check service to workmanager%22);%0A%0A        SynchronizationHelper.scheduleSync(getApplicationContext());%0A%0A        // update preference%0A        editor.putBoolean(PREF_KEY_MIGRATE_BACKGROUND_SERVICE_TO_WORKMANAGER_DONE, true);%0A        editor.apply();%0A        Log.d(TAG, %22done%22);%0A    %7D%0A%0A    private void migrateNumBreaches() %7B%0A        Log.i(TAG, %22checking if accounts with numBreaches null must be migrated%22);%0A        AccountDao accountDao = AppDatabase.get(getApplicationContext()).getAccountDao();%0A        BreachDao breachDao = AppDatabase.get(getApplicationContext()).getBreachDao();%0A%0A        new BackgroundTaskHelper%3CBoolean%3E().runInBackgroundAndConsumeOnMain(%0A                () -%3E %7B%0A                    List%3CAccount%3E accounts = accountDao.getAllWithNumBreachesNull();%0A                    Log.d(TAG, accounts.size() + %22 accounts to migrate%22);%0A%0A                    for (Account account : accounts) %7B%0A                        List%3CBreach%3E breaches = breachDao.findByAccount(account.getId());%0A                        Long numUnAck = breachDao.countUnacknowledged(account.getId());%0A                        Long numAck = breaches.size() - numUnAck;%0A                        account.setNumBreaches(breaches.size());%0A                        account.setNumAcknowledgedBreaches(numAck.intValue());%0A                        accountDao.update(account);%0A                        Log.i(TAG, %22updated account: numBreaches=%22 + account.getNumBreaches() + %22 numAcknowledgedBreaches=%22 + account.getNumAcknowledgedBreaches());%0A                    %7D%0A%0A                    return true;%0A                %7D,%0A                (b) -%3E %7B%0A                    // do nothing%0A                %7D);%0A    %7D%0A%0A
     

remove old migration code