package com.donnfelker.rxexample;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

import rx.Observable;
import rx.Subscription;
import rx.functions.Action1;
import rx.subjects.BehaviorSubject;
import rx.subjects.PublishSubject;

public class RxOrderServiceImpl implements RxOrderService, AutoCloseable {
    // IBoundOrderService is the AIDL service 
    private BehaviorSubject<IBoundOrderService> orderServiceSubject = BehaviorSubject.create();
    private CompositeSubscription compositeSubscription;

    public RxOrderServiceImpl(Context context) {

        compositeSubscription = new CompositeSubscription(); 

        Intent orderServiceIntent = new Intent(); // brevity
        context.bindService(orderServiceIntent,
                orderServiceConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection orderServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            orderServiceSubject.onNext(IBoundOrderService.Stub.asInterface(service));
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            orderServiceSubject.onCompleted();
        }
    };

    @Override
    public Observable<Order> getOrder(long orderId) {
        final PublishSubject<Order> orderSubject = PublishSubject.create();
        Subscription orderSubscription =
                orderServiceSubject.subscribe(new Action1<IBoundOrderService>() {
                    @Override
                    public void call(IBoundOrderService orderService) {
                        try {
                            orderService.getCustomer(orderId, new IBoundOrderServiceListener.Stub() {
                                @Override
                                public void onResponse(Order order) throws RemoteException {
                                    orderSubject.onNext(order);

                                }
                            });
                        } catch (RemoteException e) {
                            orderSubject.onError(e);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        orderSubject.onError(throwable);
                    }
                });

        compositeSubscription.add(orderSubscription);

        return orderSubject.asObservable();
    }

    @Override
    public void close() throws Exception {
        context.unbindService(orderServiceConnection);
        if (compositeSubscription != null && !compositeSubscription.isUnsubscribed()) {
            compositeSubscription.unsubscribe();
        }
        
    }
}