package me.thekey.android;

import android.os.AsyncTask;
import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;

import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

import me.thekey.android.exception.TheKeySocketException;
import timber.log.Timber;

interface TheKeyAttributeApi extends TheKeySessions {
    /**
     * This method will load the attributes for the default OAuth session from
     * The Key. This method is a blocking method and should never be called
     * directly on the UI thread.
     *
     * @return whether or not attributes were loaded
     */
    @WorkerThread
    default boolean loadAttributes() throws TheKeySocketException {
        return loadAttributes(getDefaultSessionGuid());
    }

    /**
     * This method will load the attributes for the specified OAuth session from
     * The Key. This method is a blocking method and should never be called
     * directly on the UI thread.
     *
     * @return whether or not attributes were loaded
     */
    @WorkerThread
    boolean loadAttributes(@Nullable String guid) throws TheKeySocketException;

    /**
     * This method will return the most recently loaded attributes for the
     * active OAuth session. This method does not attempt to load the
     * attributes if they haven't been loaded yet, to load the attributes see
     * {@link TheKey#loadAttributes()}. This is a non-blocking method and may be
     * called on the UI thread.
     *
     * @return The attributes for the current OAuth session
     */
    @NonNull
    @AnyThread
    default Attributes getCachedAttributes() {
        return getCachedAttributes(getDefaultSessionGuid());
    }

    /**
     * This method will return the most recently loaded attributes for the
     * specified OAuth session. This method does not attempt to load the
     * attributes if they haven't been loaded yet, to load the attributes see
     * {@link TheKey#loadAttributes()}. This is a non-blocking method and may be
     * called on the UI thread.
     *
     * @return The attributes for the current OAuth session
     */
    @NonNull
    @AnyThread
    Attributes getCachedAttributes(@Nullable String guid);

    /**
     * This method will return attributes for the specified user.
     * This method attempts to use the cached attributes, if the cached attributes are not valid or are stale we attempt
     * to load fresh attributes before populating the returned future.
     * This method is non-blocking, but the returned Future is blocking.
     *
     * @param guid The user we are looking for attributes for.
     * @return a Future that will eventually resolve to the user's attributes.
     */
    @NonNull
    @AnyThread
    default Future<Attributes> getAttributes(@Nullable final String guid) {
        final FutureTask<Attributes> task = new FutureTask<>(() -> {
            final Attributes attributes = getCachedAttributes(guid);

            // refresh attributes if they aren't valid or are stale
            if (!attributes.areValid() || attributes.areStale()) {
                try {
                    loadAttributes(guid);
                } catch (final TheKeySocketException e) {
                    Timber.tag("TheKey")
                            .d(e, "error loading fresh attributes for getAttributes()");
                }
                return getCachedAttributes(guid);
            }

            return attributes;
        });
        AsyncTask.THREAD_POOL_EXECUTOR.execute(task);

        return task;
    }
}

@@ -25,37 +25,8 @@
 d;%0A%0A
-import android.os.AsyncTask;%0A
 impo
@@ -206,85 +206,8 @@
 d;%0A%0A
-import java.util.concurrent.Future;%0Aimport java.util.concurrent.FutureTask;%0A%0A
 impo
@@ -1514,37 +1514,36 @@
 the current 
-OAuth session
+default user
 %0A     */%0A   
@@ -2040,34 +2040,65 @@
   *%0A     * @
-return T
+param guid The user we are getting cac
 he
+d
  attributes 
@@ -2104,34 +2104,61 @@
  for
- the current OAu
+%0A     * @return The attributes for 
 th
+e
  s
-ession
+pecified user
 %0A   
@@ -2538,20 +2538,16 @@
 thod is 
-non-
 blocking
@@ -2552,43 +2552,60 @@
 ng, 
-but the returned Future is blocking
+and should never be called directly on the UI thread
 .%0A  
@@ -2691,49 +2691,8 @@
 urn 
-a Future that will eventually resolve to 
 the 
@@ -2728,35 +2728,38 @@
   @NonNull%0A    @
-Any
+Worker
 Thread%0A    defau
@@ -2765,15 +2765,8 @@
 ult 
-Future%3C
 Attr
@@ -2771,17 +2771,16 @@
 tributes
-%3E
  getAttr
@@ -2821,81 +2821,8 @@
 ) %7B%0A
-        final FutureTask%3CAttributes%3E task = new FutureTask%3C%3E(() -%3E %7B%0A    
     
@@ -2879,28 +2879,24 @@
 tes(guid);%0A%0A
-    
         // r
@@ -2955,20 +2955,16 @@
         
-    
 if (!att
@@ -3026,22 +3026,14 @@
     
- 
-   
 try %7B%0A
-    
     
@@ -3058,36 +3058,32 @@
 tributes(guid);%0A
-    
             %7D ca
@@ -3136,20 +3136,16 @@
         
-    
 Timber.t
@@ -3157,20 +3157,16 @@
 heKey%22)%0A
-    
         
@@ -3258,18 +3258,10 @@
     
-  
-  %7D%0A    
+%7D%0A
     
@@ -3310,27 +3310,19 @@
         
-    %7D%0A%0A    
+%7D%0A%0A
         
@@ -3344,96 +3344,8 @@
 es;%0A
-        %7D);%0A        AsyncTask.THREAD_POOL_EXECUTOR.execute(task);%0A%0A        return task;%0A
     

remove Future