package com.ama.core.architecture.util.eventbus;



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


/**
 * private void test() {
 *         register(new ICallback() {
 *             @Override
 *             public void onEvent(NotifyData data) {
 *
 *             }
 *         });
 *
 *         sendEvent(1111, new NotifyData("aaaa"));
 *     }
 */
public class NotifyMan {
    private static final NotifyMan instance = new NotifyMan();
    private final String mTpTag;
    private Map<Integer, Map<ICallback, Integer>> mAllTypeObserverMap = new ConcurrentHashMap();




    private NotifyMan() {
        mTpTag = NotifyMan.class.getSimpleName() + "-" + hashCode();
        TPoolAssis.instance().configMyTPool(mTpTag, 10);
    }

    public static NotifyMan instance() {
        return instance;
    }

    public void sendEvent(int eventType, NotifyData eventData) {
        Map<ICallback, Integer> listeners = mAllTypeObserverMap.get(eventType);
        if (listeners != null && listeners.size() > 0) {
            if (eventData == null) {
                eventData = new NotifyData();
            }

            eventData.mEventType = eventType;

            for (ICallback listener : listeners.keySet()) {
                NotifyData finalEventData = eventData;
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            TPoolAssis.instance().runMain(new Runnable() {
                                @Override
                                public void run() {
                                    listener.onEvent(finalEventData);
                                }
                            });

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };

                if (listener.mNotifyInMainThread) {
                    TPoolAssis.instance().runMain(runnable);
                } else {
                    TPoolAssis.instance().runBg(runnable);
                }

            }
        }
    }



    /**
     * @param listener
     * @param eventTypes
     * @return
     */
    public void register(ICallback listener, int... eventTypes) {
        if (eventTypes != null && eventTypes.length > 0 && listener != null) {
            for (int i=0; i<eventTypes.length; i++) {
                int type = eventTypes[i];

                Map<ICallback, Integer> curTypeListenerList = mAllTypeObserverMap.get(type);
                if (curTypeListenerList == null) {
                    curTypeListenerList = new ConcurrentHashMap<>();
                    mAllTypeObserverMap.put(type, curTypeListenerList);
                }


                if (!curTypeListenerList.containsKey(listener)) {
                    curTypeListenerList.put(listener, 1);
                }
            }
        }
    }

    public void unregister(ICallback listener) {
        if (listener == null) {
            return;
        }

        TPoolAssis.instance().runBg(new Runnable() {
            @Override
            public void run() {
                try {
                    for (Map.Entry<Integer, Map<ICallback, Integer>> entry : mAllTypeObserverMap.entrySet()) {
                        entry.getValue().remove(listener);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });

    }


    //---------------------- Inner classes ----------------------
    public static class NotifyData<T> {
        public int mEventType = -123;
        public T mData;

        public NotifyData() {
        }

        public NotifyData(T data) {
            mData = data;
        }
    }

    public static abstract class ICallback {
        public boolean mNotifyInMainThread = false;

        public ICallback(boolean notifyInMainThread) {
            mNotifyInMainThread = notifyInMainThread;
        }
        public abstract void onEvent(NotifyData data);
    }


}