package com.njzscloud.common.core.mitt;

import com.njzscloud.common.core.thread.ThreadPool;
import lombok.extern.slf4j.Slf4j;

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

@Slf4j
public class Mitt {
    private static final Map<MittEvent<?>, List<MittHandler<?>>> POOL = new ConcurrentHashMap<>();
    private static final Map<MittVoidEvent, List<MittVoidHandler>> VOID_POOL = new ConcurrentHashMap<>();

    public static <T> void on(MittEvent<T> mittEvent, MittHandler<T> handlerIns) {
        POOL.compute(mittEvent, (k, v) -> {
            if (v == null) v = new LinkedList<>();
            v.add(handlerIns);
            return v;
        });
    }

    public static <T> void emit(MittEvent<T> mittEvent, T t) {
        POOL.computeIfPresent(mittEvent, (k, v) -> {
            for (MittHandler<?> handlerIns : v) {
                ThreadPool.runAsync(() -> handlerIns.on0(t))
                    .exceptionally(e -> {
                        log.error("执行失败，事件名称：{}", mittEvent, e);
                        return null;
                    });
            }
            return v;
        });
    }

    public static void on(MittVoidEvent mittEvent, MittVoidHandler handlerIns) {
        VOID_POOL.compute(mittEvent, (k, v) -> {
            if (v == null) v = new LinkedList<>();
            v.add(handlerIns);
            return v;
        });
    }

    public static void emit(MittVoidEvent mittEvent) {
        VOID_POOL.computeIfPresent(mittEvent, (k, v) -> {
            for (MittVoidHandler handlerIns : v) {
                ThreadPool.runAsync(handlerIns::on0)
                    .exceptionally(e -> {
                        log.error("执行失败，事件名称：{}", mittEvent, e);
                        return null;
                    });
            }
            return v;
        });
    }
}
