package com.ttstd.signaling.config;

import com.ttstd.signaling.handler.SignalWebSocketHandler;
import com.ttstd.signaling.security.AuthHandshakeInterceptor;
import com.ttstd.signaling.security.SecurityProperties;
import com.ttstd.signaling.security.SubProtocolHandshakeHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

import java.util.Arrays;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    private final SignalWebSocketHandler signalWebSocketHandler;
    private final AuthHandshakeInterceptor authHandshakeInterceptor;
    private final SubProtocolHandshakeHandler handshakeHandler;
    private final SecurityProperties securityProperties;

    public WebSocketConfig(SignalWebSocketHandler signalWebSocketHandler,
                           AuthHandshakeInterceptor authHandshakeInterceptor,
                           SubProtocolHandshakeHandler handshakeHandler,
                           SecurityProperties securityProperties) {
        this.signalWebSocketHandler = signalWebSocketHandler;
        this.authHandshakeInterceptor = authHandshakeInterceptor;
        this.handshakeHandler = handshakeHandler;
        this.securityProperties = securityProperties;
    }

    /**
     * 配置 WebSocket 容器的消息大小限制与会话超时。
     * <p>默认文本消息缓冲区为 8KB，WebRTC SDP（OFFER/ANSWER）消息经 JSON 包装后
     * 可能超过该限制，导致服务端抛出 TextMessageLimitException 并关闭连接。
     * 此处将文本消息上限设为 512KB，二进制消息上限设为 512KB。
     * <p>空闲超时设为 90 秒，配合客户端 PING 心跳，可尽早回收失联连接，
     * 缩短被封禁账号残留连接的存活窗口。
     */
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(512 * 1024);   // 512 KB
        container.setMaxBinaryMessageBufferSize(512 * 1024); // 512 KB
        container.setMaxSessionIdleTimeout(90_000L);         // 90 秒
        return container;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        String[] origins = Arrays.stream(securityProperties.getWebsocket().getAllowedOrigins().split(","))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .toArray(String[]::new);

        registry.addHandler(signalWebSocketHandler, "/ws/signal")
                .setHandshakeHandler(handshakeHandler)
                .addInterceptors(authHandshakeInterceptor)
                .setAllowedOriginPatterns(origins);
    }
}
