package com.thebluealliance.androidclient.accounts;

import com.thebluealliance.androidclient.config.AppConfig;
import com.thebluealliance.androidclient.auth.User;
import com.thebluealliance.androidclient.mytba.MyTbaRegistrationService;
import com.thebluealliance.androidclient.mytba.MyTbaUpdateService;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.annotation.Nullable;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * A class to handle state surrounding MyTba
 * Backed by {@link SharedPreferences}
 */
@Singleton
public class AccountController {

    private static final String PREF_MYTBA_ENABLED = "mytba_enabled";
    private static final String PREF_SELECTED_ACCOUNT = "selected_account";

    private final SharedPreferences mPreferences;
    private final AccountManager mAccountManager;
    private final AppConfig mAppConfig;
    private final String mAccountType;

    @Inject
    public AccountController(
            SharedPreferences preferences,
            AccountManager accountManager,
            AppConfig appConfig,
            String accountType) {
        mPreferences = preferences;
        mAccountManager = accountManager;
        mAppConfig = appConfig;
        mAccountType = accountType;
    }

    public void setMyTbaEnabled(boolean enabled) {
        mPreferences.edit().putBoolean(PREF_MYTBA_ENABLED, enabled).apply();
    }

    public boolean isMyTbaEnabled() {
        return mPreferences.getBoolean(PREF_MYTBA_ENABLED, false) && !getWebClientId().isEmpty();
    }

    public void setSelectedAccount(String account) {
        mPreferences.edit().putString(PREF_SELECTED_ACCOUNT, account).apply();
    }

    public String getSelectedAccount() {
        return mPreferences.getString(PREF_SELECTED_ACCOUNT, "");
    }

    public boolean isAccountSelected() {
        return !getSelectedAccount().isEmpty();
    }

    public @Nullable Account getCurrentAccount() {
        Account[] accounts = mAccountManager.getAccountsByType(mAccountType);
        String selectedAccount = getSelectedAccount();
        for (Account account : accounts) {
            if (account.name.equals(selectedAccount)) return account;
        }
        return null;
    }

    public void onAccountConnect(Context context, User user) {
        setMyTbaEnabled(true);
        registerSystemAccount(user.getEmail());
        setSelectedAccount(user.getEmail());
        registerForGcm(context);
        loadMyTbaData(context);
    }

    public String getWebClientId() {
        return mAppConfig.getString("appspot_webClientId");
    }

    private boolean registerSystemAccount(String accountName) {
        if (mAccountManager.getAccountsByType(mAccountType).length == 0) {
            Account account = new Account(accountName, mAccountType);
            return mAccountManager.addAccountExplicitly(account, null, null);
        }

        // An account of this type already exists
        return true;
    }

    private void registerForGcm(Context context) {
        context.startService(new Intent(context, MyTbaRegistrationService.class));
    }

    private void loadMyTbaData(Context context) {
        Intent intent = MyTbaUpdateService.newInstance(context, true, true);
        context.startService(intent);
    }

}

@@ -46,16 +46,68 @@
 ounts;%0A%0A
+import com.thebluealliance.androidclient.TbaLogger;%0A
 import c
@@ -2140,16 +2140,52 @@
 ccount%5B%5D
+ accounts;%0A        try %7B%0A           
  account
@@ -2229,32 +2229,238 @@
 (mAccountType);%0A
+        %7D catch (SecurityException e) %7B%0A            // We don't have the correct permissions%0A            TbaLogger.w(%22Can't get current local account, no permission%22, e);%0A            return null;%0A        %7D%0A
         String s
@@ -3088,59 +3088,333 @@
     
-if (mAccountManager.getAccountsByType(mAccountType)
+Account%5B%5D accounts;%0A        try %7B%0A            accounts = mAccountManager.getAccountsByType(mAccountType);%0A        %7D catch (SecurityException e) %7B%0A            // We don't have the correct permissions%0A            TbaLogger.w(%22Can't add local account, no permission%22, e);%0A            return false;%0A        %7D%0A        if (accounts
 .len

Handle potential lack of permissions for accounts