package com.eactive.eai.custom.alarm.ums;

import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.eactive.eai.common.util.Logger;
import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload;

@Component
public class UmsSendManager {
	
	protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
    // 1. I/O 처리를 위한 전용 스레드 풀 (예: 최대 10개 스레드)
    private final ExecutorService ioExecutor = Executors.newFixedThreadPool(10);
    private final ScheduledExecutorService scheduler;
    
    // 2. 메모리 보호를 위해 크기 제한이 있는 큐 권장 (선택사항)
    private final Queue<UmsRequestPayload> queue = new ConcurrentLinkedQueue<>();

    @Autowired
    UmsService umsService;

    public UmsSendManager() {
        this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
            Thread t = new Thread(r);
            t.setName("UmsSendManager-worker");
            return t;
        });

        scheduler.scheduleWithFixedDelay(() -> {
            try {
                sendMessage();
            } catch (Throwable e) {
                logger.error("UMS 스케줄러 실행 중 오류", e);
            }
        }, 0, 30, TimeUnit.SECONDS);
    }

    void sendMessage() {
        UmsRequestPayload payload;
        // 3. 한 번의 주기당 최대 처리량 제한 (필요시)
        int count = 0;
        while ((payload = queue.poll()) != null && count < 1000) { 
            final UmsRequestPayload finalPayload = payload;
            
            // 전용 Executor를 사용하여 공용 풀 보호
            CompletableFuture.runAsync(() -> {
                try {
                    umsService.send(finalPayload);
                } catch (Exception e) {
                    logger.error("UMS 전송 실패", e);
                }
            }, ioExecutor);
            count++;
        }
    }

    // 4. 안전한 종료 처리
    @PreDestroy
    public void stop() {
        scheduler.shutdown();
        ioExecutor.shutdown();
        try {
            if (!ioExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                ioExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            ioExecutor.shutdownNow();
            logger.error("UmsSendManager shutdownNow.", e);
        }
    }

    public void enqueue(UmsRequestPayload payload) {
        queue.offer(payload);
    }
}
