package com.frame.base.bus;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;

public class RxBus {

    private volatile static RxBus sRxbus;
    private final Subject<Object> mBus;
    private final Map<Class<?>,Object> mStickyEventMap;

    public RxBus() {
        mBus = PublishSubject.create().toSerialized();
        mStickyEventMap = new ConcurrentHashMap<>();
    }

    private static RxBus getInstance(){
        if (sRxbus ==null){
            synchronized (RxBus.class){
                if (sRxbus ==null){
                    sRxbus = new RxBus();
                }
            }
        }
        return sRxbus;

    }


    /**
     * 普通订阅解绑
     * @param disposable
     */
    public static  void  unBund(CompositeDisposable disposable){
        if (null != disposable && !disposable.isDisposed()){
            disposable.clear();
        }
    }

    /**
     * 发送事件
     * @param event
     */
    public static void post(Object event){
        getInstance().mBus.onNext(event);
    }


    /**
     * 根据传递的eventType 类型舞蹈特定类型(eventType)的观察者
     * @param eventType
     * @param <T>
     * @return
     */
    public static <T> Observable<T> tObservable(final Class<T> eventType){
        return  getInstance().mBus.ofType(eventType).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 根据传递的 eventType 类型返回特定类型（eventType) 的被观察者
     * @param eventType
     * @param <T>
     * @return
     */
    public static <T> Observable<T> toObservableSticky(final Class<T> eventType){
        synchronized (getInstance().mStickyEventMap){
            Observable<T> observable = getInstance().mBus.ofType(eventType);
            final Object event = getInstance().mStickyEventMap.get(eventType);
            if (event !=null){
                return observable.mergeWith(Observable.create(new ObservableOnSubscribe<T>() {
                    @Override
                    public void subscribe(ObservableEmitter<T> emitter) throws Exception {
                        emitter.onNext(eventType.cast(event));
                    }
                }));
            }else {
                return observable;
            }
        }
    }


    /**
     * 是否有订阅者
     * @return
     */
    public boolean hasObservers(){
        return mBus.hasObservers();
    }


    public void reset(){
        sRxbus =null;
    }


    /**
     * 根据eventType获取sticky事件
     * @param eventType
     * @param <T>
     * @return
     */
    public  <T> T getStickyEvent(Class<T> eventType){
        synchronized (mStickyEventMap){
            return eventType.cast(mStickyEventMap.get(eventType));
        }
    }

    /**
     * 移除指定eventType的Sticky事件
     * @param eventType
     * @param <T>
     * @return
     */
    public <T> T removeStickyEvent(Class<T> eventType){
        synchronized (mStickyEventMap){
            return eventType.cast(mStickyEventMap.remove(eventType));
        }
    }


    /**
     * 移除所有的Sticky事件
     */
    public void removeAllStickyEvents(){
        synchronized (mStickyEventMap){
            mStickyEventMap.clear();
        }
    }



}
