package com.khmelenko.lab.travisclient.network.retrofit;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.khmelenko.lab.travisclient.common.Constants;
import com.khmelenko.lab.travisclient.storage.AppSettings;
import com.khmelenko.lab.travisclient.util.PackageUtils;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.IOException;

import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.client.OkClient;
import retrofit.converter.GsonConverter;

/**
 * REST client for Network communication
 *
 * @author Dmytro Khmelenko
 */
public final class RestClient {
    private static final String GITHUB_URL = Constants.GITHUB_URL;

    private TravisApiService mApiService;
    private GithubApiService mGithubApiService;
    private RawApiService mRawApiService;

    private RestClient() {

        final String travisUrl = AppSettings.getServerUrl();
        updateTravisEndpoint(travisUrl);

        // rest adapter for github API service
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(GITHUB_URL)
                .setConverter(new GsonConverter(constructGsonConverter()))
                .setErrorHandler(new RestErrorHandling())
                .build();
        mGithubApiService = restAdapter.create(GithubApiService.class);
    }

    /**
     * Creates new instance of the rest client
     *
     * @return Instance
     */
    public static RestClient newInstance() {
        return new RestClient();
    }

    /**
     * Updates Travis endpoint
     *
     * @param newEndpoint New endpoint
     */
    public void updateTravisEndpoint(String newEndpoint) {
        // rest adapter for travis API service
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(newEndpoint)
                .setConverter(new GsonConverter(constructGsonConverter()))
                .setRequestInterceptor(constructRequestInterceptor())
                .setErrorHandler(new RestErrorHandling())
                .build();
        mApiService = restAdapter.create(TravisApiService.class);

        final OkHttpClient client = new OkHttpClient();
        client.setFollowRedirects(false);

        // rest adapter for raw calls
        restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(newEndpoint)
                .setConverter(new GsonConverter(constructGsonConverter()))
                .setErrorHandler(new RestErrorHandling())
                .setClient(new OkClient(client))
                .build();
        mRawApiService = restAdapter.create(RawApiService.class);
    }

    /**
     * Constructs request interceptor
     *
     * @return Request interceptor
     */
    private RequestInterceptor constructRequestInterceptor() {
        RequestInterceptor requestInterceptor = new RequestInterceptor() {
            @Override
            public void intercept(RequestFacade request) {
                String userAgent = String.format("TravisClient/%1$s", PackageUtils.getAppVersion());
                request.addHeader("User-Agent", userAgent);
                request.addHeader("Accept", "application/vnd.travis-ci.2+json");

                String accessToken = AppSettings.getAccessToken();
                if (!TextUtils.isEmpty(accessToken)) {
                    String headerValue = String.format("token %1$s", accessToken);
                    request.addHeader("Authorization", headerValue);
                }
            }
        };
        return requestInterceptor;
    }

    /**
     * Construct Gson converter
     *
     * @return Gson converter
     */
    private Gson constructGsonConverter() {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                .registerTypeAdapterFactory(new ItemTypeAdapterFactory())
                .create();
        return gson;
    }

    /**
     * Gets travis API service
     *
     * @return Travis API service
     */
    public TravisApiService getApiService() {
        return mApiService;
    }

    /**
     * Gets Github API service
     *
     * @return Github API service
     */
    public GithubApiService getGithubApiService() {
        return mGithubApiService;
    }

    /**
     * Gets Raw API service
     *
     * @return Raw API service
     */
    public RawApiService getRawApiService() {
        return mRawApiService;
    }

    /**
     * Executes single request
     *
     * @param url URL for request
     * @return Response
     */
    public Response singleRequest(String url) throws IOException {
        OkHttpClient client = new OkHttpClient();
        client.setFollowRedirects(false);

        Request request = new Request.Builder()
                .url(url)
                .build();

        Response response = client.newCall(request).execute();
        return response;
    }
}

@@ -933,22 +933,88 @@
 ate 
-RestClient() %7B
+OkHttpClient mHttpClient;%0A%0A    private RestClient() %7B%0A%0A        initHttpClient();
 %0A%0A  
@@ -1548,32 +1548,211 @@
 .class);%0A    %7D%0A%0A
+    /**%0A     * Initializes HTTP client%0A     */%0A    private void initHttpClient() %7B%0A        mHttpClient = new OkHttpClient();%0A        mHttpClient.setFollowRedirects(false);%0A    %7D%0A%0A
     /**%0A     * C
@@ -2571,107 +2571,8 @@
 );%0A%0A
-        final OkHttpClient client = new OkHttpClient();%0A        client.setFollowRedirects(false);%0A%0A
     
@@ -2924,17 +2924,22 @@
 kClient(
-c
+mHttpC
 lient))%0A
@@ -5018,24 +5018,25 @@
 ption %7B%0A
+%0A
         
 OkHttpCl
@@ -5031,59 +5031,14 @@
     
-OkHttpClient client = new OkHttpClient();%0A        c
+mHttpC
 lien
@@ -5196,17 +5196,22 @@
 ponse = 
-c
+mHttpC
 lient.ne

Improve initialization of the OkHttpClient