package com.app.baselibrary.baseRx;

import android.support.annotation.NonNull;

import com.app.baselibrary.commonUtil.LogUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.subjects.PublishSubject;
import rx.subjects.Subject;

/**
 * Desc: 使用Rx实现的事件订阅者；
 * Author: pl
 * Date: 2017-04-13 16:05
 */

public class RxBus {

    private static final String TAG = "RxBus";

    private static RxBus mInstance;

    /**
     * 分段锁，并发控制集合；
     */
    private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<Object, List<Subject>>();

    /**
     * 单例；
     *
     * @return
     */
    public static RxBus getDefault() {
        if (null == mInstance) {
            synchronized (RxBus.class) {
                if (null == mInstance) {
                    mInstance = new RxBus();
                }
            }
        }
        return mInstance;
    }

    /**
     * 订阅事件源
     *
     * @param mObservable
     * @param mAction1
     * @return
     */
    public RxBus OnEvent(Observable<?> mObservable, Action1<Object> mAction1) {
        mObservable.observeOn(AndroidSchedulers.mainThread()).subscribe(mAction1, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                throwable.printStackTrace();
            }
        });
        return getDefault();
    }


    /**
     * 注册订阅者；
     *
     * @param tag
     * @param <T>
     * @return
     */
    public <T> Observable<T> register(Object tag) {
        List<Subject> subjectList = subjectMapper.get(tag);
        if (null == subjectList) {
            subjectList = new ArrayList<>();
            subjectMapper.put(tag, subjectList);
        }
        Subject<T, T> subject;
        subjectList.add(subject = PublishSubject.create());
        LogUtil.i(TAG, "register:" + tag + "_____size:" + subjectList.size());
        return subject;
    }


    /**
     * 移除注册项；
     *
     * @param tag
     */
    public void unregister(Object tag) {

        List<Subject> subjectList = subjectMapper.get(tag);
        if (null != subjectList)
            subjectMapper.remove(tag);
    }

    /**
     * 取消注册；
     *
     * @param tag
     * @param observable
     * @return
     */
    public RxBus unregister(@NonNull Object tag, @NonNull Observable<?> observable) {
        List<Subject> subjectList = subjectMapper.get(tag);
        if (null != subjectList) {
            if (subjectList.contains((Subject<?, ?>) observable))
                subjectList.remove((Subject<?, ?>) observable);

            if (!isEmpty(subjectList)) {
                subjectMapper.remove(tag);
                LogUtil.i(TAG, "unregister:" + tag);
            }
        }


        return getDefault();
    }

    public void post(@NonNull Object content) {
        post(content.getClass().getName(), content);
    }

    /**
     * 发送事件，不如说是触发事件；
     *
     * @param tag
     * @param event
     * @return
     */
    public void post(@NonNull Object tag, @NonNull Object event) {

        List<Subject> subjectList = subjectMapper.get(tag);
        if (!isEmpty(subjectList)) {
            for (Subject subject :
                    subjectList) {
                subject.onNext(event);
                LogUtil.i(TAG, "onEvent" + "eventName:" + tag);
            }
        }

    }


    public static boolean isEmpty(Collection<Subject> collection) {
        return null == collection || collection.isEmpty();
    }
}
