package com.jug6ernaut.network.authenticator.client;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.jug6ernaut.android.logging.Logger;
import retrofit.Profiler;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.client.OkClient;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import static retrofit.Profiler.RequestInformation;

/**
 * Created with IntelliJ IDEA.
 * User: williamwebb
 * Date: 9/21/13
 * Time: 10:17 AM
 */
public abstract class AbstractWebManager<T> {

//    private static Logger logger = Logger.getLogger(AbstractWebManager.class);
    private static Logger retrologger = Logger.getLogger("Retrofit");
    private static Boolean connectionReceiverRegistered = false;
    private static RestAdapter restAdapter;
    protected Backend backend;
    T t;

    PublishSubject<Boolean> connectionEventPublisher = PublishSubject.create();
    PublishSubject<RequestObject> requestEventPublisher = PublishSubject.create();


    protected AbstractWebManager(Backend backend){
        this.backend = backend;
        initAdapter();
        synchronized (connectionReceiverRegistered){
            if(!connectionReceiverRegistered){
                backend.app.registerReceiver(CONNECTION_RECIEVER, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
                connectionReceiverRegistered = true;
            }
        }
    }

    public static class RequestObject{
        public final RequestInformation info;
        public final long l;
        public final int i;
        public final Object o;

        private RequestObject(RequestInformation info,long l, int i, Object o){
            this.info = info;
            this.l = l;
            this.i = i;
            this.o = o;
        }
    }

    private void initAdapter(){

        if(restAdapter == null){
            RestAdapter.Builder builder = new RestAdapter.Builder();
            builder.setClient( new OkClient( backend.client ) )
                    .setEndpoint(backend.serverUrl)
                    .setLogLevel(RestAdapter.LogLevel.FULL)
                    .setLog(new RestAdapter.Log() {
                        @Override
                        public void log(String s) {
                            retrologger.debug(s);
                        }
                    })
                    .setRequestInterceptor(new RequestInterceptor() {
                        @Override
                        public void intercept(RequestFacade requestFacade) {
                            onRequest(requestFacade);
                        }
                    })
                    .setProfiler(new Profiler() {
                        @Override
                        public Object beforeCall() {
                            return null;
                        }

                        @Override
                        public void afterCall(RequestInformation requestInformation, long l, int i, Object o) {
                            retrologger.error("afterCall(" + requestInformation.getRelativePath() + ":" + requestInformation.getMethod() + ": " + i + " : " + o);
                            requestEventPublisher.onNext(new RequestObject(requestInformation,l,i,o));
                        }
                    });
//                    .setErrorHandler(new ErrorHandler() {
//                        @Override
//                        public Throwable handleError(RetrofitError retrofitError) {
//                            return onError(retrofitError.getResponse().getStatus());
//                        }
//                    });
            restAdapter = builder.build();
        }

        Class<T> type = getType();
        if(type==null)throw new IllegalStateException("getType can not be null");

        t = restAdapter.create(type);
    }

    public T getWebService(){
        return t;
    }

    public final void addRequestInterceptor(Observer<RequestObject> observer){
        Subscription subscription = requestEventPublisher
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    protected RequestInterceptor.RequestFacade onRequest(RequestInterceptor.RequestFacade requestFacade){
        return requestFacade;
    }

    protected abstract Class<T> getType();

    public static interface ConnectionListner{
        public void onConnectionChange(boolean connected);
    }

    private void fireConnectionChange(final boolean connected){
        for(ConnectionListner listner : listeners){
            listner.onConnectionChange(connected);
        }
    }

    private static final List<ConnectionListner> listeners = new CopyOnWriteArrayList<ConnectionListner>();
    public void addConnectionListener(ConnectionListner listener){
        listeners.add(listener);
    }

    public void removeConnectionListener(ConnectionListner listener){
        listeners.remove(listener);
    }

    private BroadcastReceiver CONNECTION_RECIEVER = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
            NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();

            if (activeNetInfo != null && activeNetInfo.getState() == NetworkInfo.State.CONNECTED) {
                retrologger.debug("Network " + activeNetInfo.getTypeName() + " connected");
                fireConnectionChange(true);
            }

            if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
                retrologger.debug("There's no network connectivity");
                fireConnectionChange(false);
            }
        }
    };

}

@@ -434,168 +434,8 @@
 ent;
-%0Aimport rx.Observer;%0Aimport rx.Subscription;%0Aimport rx.android.schedulers.AndroidSchedulers;%0Aimport rx.schedulers.Schedulers;%0Aimport rx.subjects.PublishSubject;
 %0A%0Aim
@@ -510,61 +510,8 @@
 t;%0A%0A
-import static retrofit.Profiler.RequestInformation;%0A%0A
 /**%0A
@@ -648,16 +648,20 @@
 r%3CT%3E %7B%0A%0A
+    
 //    pr
@@ -729,24 +729,24 @@
 ger.class);%0A
-
     private 
@@ -957,173 +957,8 @@
 t;%0A%0A
-    PublishSubject%3CBoolean%3E connectionEventPublisher = PublishSubject.create();%0A    PublishSubject%3CRequestObject%3E requestEventPublisher = PublishSubject.create();%0A%0A%0A
     
@@ -1373,381 +1373,8 @@
  %7D%0A%0A
-    public static class RequestObject%7B%0A        public final RequestInformation info;%0A        public final long l;%0A        public final int i;%0A        public final Object o;%0A%0A        private RequestObject(RequestInformation info,long l, int i, Object o)%7B%0A            this.info = info;%0A            this.l = l;%0A            this.i = i;%0A            this.o = o;%0A        %7D%0A    %7D%0A%0A
     
@@ -1572,60 +1572,8 @@
 ) )%0A
-                    .setEndpoint(backend.serverUrl)%0A
     
@@ -1857,32 +1857,82 @@
              %7D)%0A
+                    .setServer(backend.serverUrl)%0A
                 
@@ -2653,19 +2653,17 @@
 () + %22:%22
- + 
++
 requestI
@@ -2699,20 +2699,8 @@
  + i
- + %22 : %22 + o
 );%0A 
@@ -2730,80 +2730,17 @@
     
-requestEventPublisher.onNext(new RequestObject(requestInformation,l,i,o)
+onError(i
 );%0A 
@@ -3392,281 +3392,71 @@
    p
-ublic final void addRequestInterceptor(Observer%3CRequestObject%3E observer)%7B%0A        Subscription subscription = requestEventPublisher%0A                .subscribeOn(Schedulers.io())%0A                .observeOn(AndroidSchedulers.mainThread())%0A                .subscribe(observer)
+rotected int onError(int statusCode)%7B%0A        return statusCode
 ;%0A  

Revert file that should have not been commited