package mil.nga.giat.mage.sdk.http;

import android.content.Context;
import android.preference.PreferenceManager;
import android.util.Log;

import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;

import mil.nga.giat.mage.sdk.R;
import mil.nga.giat.mage.sdk.event.IEventDispatcher;
import mil.nga.giat.mage.sdk.event.IUserEventListener;
import mil.nga.giat.mage.sdk.utils.UserUtility;

import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;

/**
 * Always use the {@link HttpClientManager#httpClient} for making ALL
 * requests to the server. This class adds request and response interceptors to
 * pass things like a token and handle errors like 403 and 401.
 *
 * @author newmanw
 */
public class HttpClientManager implements IEventDispatcher<IUserEventListener> {

    private static final String LOG_NAME = HttpClientManager.class.getName();

    private static HttpClientManager httpClientManager;
    private String userAgent;

    private Context context;
    private Collection<IUserEventListener> listeners = new CopyOnWriteArrayList<>();

    public static HttpClientManager getInstance(final Context context) {
        if (context == null) {
            return null;
        }

        if (httpClientManager == null) {
            String userAgent = System.getProperty("http.agent");
            userAgent = (userAgent == null) ? "" : userAgent;

            httpClientManager = new HttpClientManager(context, userAgent);
        }

        return httpClientManager;
    }

    private HttpClientManager(Context context, String userAgent) {
        this.context = context;
        this.userAgent = userAgent;
    }

    public OkHttpClient httpClient() {
        OkHttpClient client = new OkHttpClient();

        client.interceptors().add(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request.Builder builder = chain.request().newBuilder();

                // add token
                String token = PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.tokenKey), null);
                if (token != null && !token.trim().isEmpty()) {
                    builder.addHeader("Authorization", "Bearer " + token);
                }

                // add Accept-Encoding:gzip
                builder.addHeader("Accept-Encoding", "gzip")
                    .addHeader("User-Agent", userAgent);

                Response response = chain.proceed(builder.build());

                int statusCode = response.code();
                if (statusCode == HTTP_UNAUTHORIZED) {
                    UserUtility userUtility = UserUtility.getInstance(context);

                    // If token has not expired yet, expire it and send notification to listeners
                    if (!userUtility.isTokenExpired()) {
                        UserUtility.getInstance(context).clearTokenInformation();

                        for (IUserEventListener listener : listeners) {
                            listener.onTokenExpired();
                        }
                    }

                    Log.w(LOG_NAME, "TOKEN EXPIRED");
                } else if (statusCode == HTTP_NOT_FOUND) {
                    Log.w(LOG_NAME, "404 Not Found.");
                }

                return response;
            }
        });

        return client;
    }

    @Override
    public boolean addListener(IUserEventListener listener) {
        return listeners.add(listener);
    }

    @Override
    public boolean removeListener(IUserEventListener listener) {
        return listeners.remove(listener);
    }
}
@@ -394,16 +394,54 @@
 rayList;
+%0Aimport java.util.concurrent.TimeUnit;
 %0A%0Aimport
@@ -2014,16 +2014,125 @@
 lient();
+%0A        client.setConnectTimeout(30, TimeUnit.SECONDS);%0A        client.setReadTimeout(30, TimeUnit.SECONDS);
 %0A%0A      

Set OkHttp client timeouts