package com.backendsys.modules.sse.emitter;

import com.backendsys.modules.sse.utils.SseEmitterUTF8;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class SseEmitterManager {
    // 单例实例
    private static final SseEmitterManager INSTANCE = new SseEmitterManager();
    // 存储SseEmitter的线程安全列表
    public final ConcurrentHashMap<String, SseEmitterUTF8> emitters = new ConcurrentHashMap<>();

    // 私有构造函数，防止外部直接实例化
    private SseEmitterManager() {}

    // 公共静态方法，获取单例实例
    public static SseEmitterManager getInstance() {
        return INSTANCE;
    }
    public ConcurrentHashMap<String, SseEmitterUTF8> getEmitters() { return emitters; }

    // 公共方法，供外部添加SseEmitter
    public void addEmitter(String emitterKey, SseEmitterUTF8 emitter) {
        this.emitters.put(emitterKey, emitter);
        emitter.onTimeout(() -> {
            System.out.println("(sse)(onTimeout) emitter 超时, emitterKey: " + emitterKey);
            removeEmitter(emitter);
        });
        emitter.onCompletion(() -> {
            System.out.println("(sse)(onCompletion) emitter 中断, emitterKey: " + emitterKey);
            removeEmitter(emitter);
        });
    }
    // 公共方法，供外部移除SseEmitter
    public SseEmitterUTF8 getEmitter(String emitterKey) {
        return this.emitters.get(emitterKey);
    }
    // 公共方法，获取所有SseEmitter实例
    public ConcurrentHashMap<String, SseEmitterUTF8> getAllEmitters() {
        return this.emitters;
    }
    // 公共方法，供外部移除SseEmitter
    public void removeEmitter(SseEmitterUTF8 emitter) {
        try {
            // System.out.println("(removeEmitter) emitter 关闭: " + emitter);
            emitter.complete();
        } catch (Exception e) {
            System.err.println("Failed to forcefully close emitter: " + e.getMessage());
        } finally {
            this.emitters.values().removeIf(e -> e == emitter); // 安全移除
        }
    }
    // 公共方法，供外部移除SseEmitter (全部)
    public void removeAllEmitter() {
        for (SseEmitterUTF8 emitter : emitters.values()) {
            removeEmitter(emitter);
        }
    }
}