package com.simperium.android;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;

import com.simperium.Simperium;
import com.simperium.Version;
import com.simperium.client.ClientFactory;
import com.simperium.util.Uuid;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

/**
 * Refactoring as much of the android specific components of the client
 * and decoupling different parts of the API.
 */
public class AndroidClient implements ClientFactory {

    public static final String SHARED_PREFERENCES_NAME = "simperium";

    public static final String DEFAULT_DATABASE_NAME = "simperium-store";

    public static final String SESSION_ID_PREFERENCE = "simperium-session-id";

    protected Context mContext;
    protected SQLiteDatabase mDatabase;

    protected ExecutorService mExecutor = Executors.newFixedThreadPool(1);

    public AndroidClient(Context context){
        mContext = context;
        mDatabase = mContext.openOrCreateDatabase(DEFAULT_DATABASE_NAME, 0, null);
    }

    public static SharedPreferences sharedPreferences(Context context){
        return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
    }

    @Override
    public VolleyAuthClient buildAuthProvider(String appId, String appSecret){
        VolleyAuthClient client = new VolleyAuthClient(appId, appSecret, mContext);
        return client;
    }

    @Override
    public WebSocketManager buildChannelProvider(String appId){
        // Simperium Bucket API
        SharedPreferences preferences = sharedPreferences(mContext);
        String sessionToken = null;

        if (preferences.contains(SESSION_ID_PREFERENCE)) {
            try {
                sessionToken = preferences.getString(SESSION_ID_PREFERENCE, null);
            } catch (ClassCastException e) {
                sessionToken = null;
            }
        }

        if (sessionToken == null) {
            sessionToken = Uuid.uuid().substring(0,6);
            preferences.edit().putString(SESSION_ID_PREFERENCE, sessionToken).apply();
        }

        String sessionId = String.format("%s-%s", Version.LIBRARY_NAME, sessionToken);
        return new WebSocketManager(mExecutor, appId, sessionId, new QueueSerializer(mDatabase));
    }

    @Override
    public PersistentStore buildStorageProvider(){
        return new PersistentStore(mDatabase);
    }

    @Override
    public GhostStore buildGhostStorageProvider(){
        return new GhostStore(mDatabase);
    }

    @Override
    public LruCacheProvider buildObjectCacheProvider(){
        return new LruCacheProvider();
    }

    @Override
    public Executor buildExecutor(){
        return mExecutor;
    }
}
@@ -408,16 +408,42 @@
 rvice;%0A%0A
+import android.util.Log;%0A%0A
 /**%0A * R
@@ -615,16 +615,81 @@
 tory %7B%0A%0A
+    public static final String TAG = %22Simperium.AndroidClient%22;%0A%0A
     publ
@@ -1022,42 +1022,8 @@
 utor
- = Executors.newFixedThreadPool(1)
 ;%0A%0A 
@@ -1056,32 +1056,297 @@
 ntext context)%7B%0A
+        int threads = Runtime.getRuntime().availableProcessors();%0A        if (threads %3E 1) %7B%0A            threads -= 1;%0A        %7D%0A%0A        Log.d(TAG, String.format(%22Using %25d cores for executors%22, threads));%0A        mExecutor = Executors.newFixedThreadPool(threads);%0A
         mContext

Determine threadpool size dynamically based onn available cores