package cn.com.poc.common.utils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author alex.yao
 * @date 2025/3/4
 */
public class SSEUtil implements AutoCloseable {

    private final Logger logger = LoggerFactory.getLogger(SSEUtil.class);

    private final ServletOutputStream outputStream;

    private final Object lock = new Object(); // 添加锁对象

    private volatile boolean closed = false; // 添加关闭状态标记

    public SSEUtil() throws IOException {
        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = servletRequestAttributes.getResponse();
        if (response == null) {
            throw new IOException("无法获取HttpServletResponse");
        }
        response.setContentType("text/event-stream;charset=UTF-8");
        outputStream = response.getOutputStream();
    }

    public SSEUtil(HttpServletResponse response) {
        try {
            response.setContentType("text/event-stream;charset=UTF-8");
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            throw new RuntimeException("无法获取HttpServletResponse");
        }
    }

    public void send(String data) throws IOException {
        if (closed) {
            throw new IOException("SSE连接已关闭");
        }
        synchronized (lock) {
            if (closed) {
                throw new IOException("SSE连接已关闭");
            }
            String message = "data: " + data + "\n\n";
            outputStream.write(message.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
        }
    }

    public boolean complete() {
        if (closed) {
            return true; // 已经关闭，返回true
        }
        synchronized (lock) {
            if (closed) {
                return true;
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                logger.error("无法关闭sse连接:{}", e.getMessage());
                return false;
            }
            return true;
        }
    }

    public boolean completeByError(String errorMsg) {
        if (closed) {
            return true; // 已经关闭，返回true
        }
        synchronized (lock) {
            if (closed) {
                return true;
            }
            try {
                String mess = "data: " + errorMsg + "\n\n";
                outputStream.write(mess.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                logger.error("无法关闭sse连接:{}", e.getMessage());
                return false;
            }
            return true;
        }
    }

    @Override
    public void close() throws Exception {
        complete();
    }
}
