package me.thekey.android;

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

import me.thekey.android.exception.TheKeySocketException;

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);
}

@@ -17,24 +17,53 @@
 y.android;%0A%0A
+import android.os.AsyncTask;%0A
 import andro
@@ -227,24 +227,101 @@
 kerThread;%0A%0A
+import java.util.concurrent.Future;%0Aimport java.util.concurrent.FutureTask;%0A%0A
 import me.th
@@ -2271,11 +2271,1114 @@
 g guid);
+%0A%0A    /**%0A     * This method will return attributes for the specified user.%0A     * This method attempts to use the cached attributes, if the cached attributes are not valid or are stale we attempt%0A     * to load fresh attributes before populating the returned future.%0A     * This method is non-blocking, but the returned Future is blocking.%0A     *%0A     * @param guid The user we are looking for attributes for.%0A     * @return a Future that will eventually resolve to the user's attributes.%0A     */%0A    @NonNull%0A    @AnyThread%0A    default Future%3CAttributes%3E getAttributes(@Nullable final String guid) %7B%0A        final FutureTask%3CAttributes%3E task = new FutureTask%3C%3E(() -%3E %7B%0A            final Attributes attributes = getCachedAttributes(guid);%0A%0A            // refresh attributes if they aren't valid or are stale%0A            if (!attributes.areValid() %7C%7C attributes.areStale()) %7B%0A                loadAttributes(guid);%0A                return getCachedAttributes(guid);%0A            %7D%0A%0A            return attributes;%0A        %7D);%0A        AsyncTask.THREAD_POOL_EXECUTOR.execute(task);%0A%0A        return task;%0A    %7D
 %0A%7D%0A

add a getAttributes method that returns a future that will resolve to fresh attributes.