package com.kospo.talk.config.ws;


import com.kospo.talk.config.interceptor.ChatInfoInterceptor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry;
import org.springframework.messaging.simp.broker.SubscriptionRegistry;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

@Configuration
@EnableWebSocketMessageBroker // 문자 채팅용
@RequiredArgsConstructor
@Slf4j
public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
    private final ChatInfoInterceptor chatInfoInterceptor;
//    private final CustomWebSocketHandler customWebSocketHandler;
    @Value("${rabbitmq.connection.host}")
    private String host;
    @Value("${rabbitmq.connection.username}")
    private String username;
    @Value("${rabbitmq.connection.password}")
    private String password;

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/stomp/talk", "/stomp/file")
                .setAllowedOriginPatterns("*")
                .withSockJS()
                .setHeartbeatTime(20000)
                .setStreamBytesLimit(512 * 1024) // 5MB
                .setHttpMessageCacheSize(1000)
                .setWebSocketEnabled(true)
                .setSessionCookieNeeded(true)
                .setDisconnectDelay(15000); // 연결 해지시 체크 시간

        registry.addEndpoint("/stomp/ws")
                .setAllowedOriginPatterns("*");
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        log.debug("websocketbrokerConfigurer");
        config.setPathMatcher((new AntPathMatcher(".")));
        config.setApplicationDestinationPrefixes("/pub");

        config.enableStompBrokerRelay("/queue", "/topic", "/exchange", "/amq/queue")
                .setRelayHost(host)
                .setRelayPort(61613)
                .setSystemLogin(username)
                .setSystemPasscode(password)
                .setClientLogin(username)
                .setClientPasscode(password)
                .setSystemHeartbeatSendInterval(20000)
                .setSystemHeartbeatReceiveInterval(20000);
    }


    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
        registration.setMessageSizeLimit(1024 * 1024); // 1mb
        registration.setSendBufferSizeLimit(1024 * 1024); // 1mb
        registration.setSendTimeLimit(20 * 1000); // 20 seconds
//        registration.setDecoratorFactories(customWebSocketHandler);
    }


    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(chatInfoInterceptor);
        registration.taskExecutor().corePoolSize(16)
                .maxPoolSize(32)
                .keepAliveSeconds(360);
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.interceptors(chatInfoInterceptor);
        registration.taskExecutor().corePoolSize(16)
                .maxPoolSize(32);
    }

    @Bean
    public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(1024 * 1024);
        container.setMaxBinaryMessageBufferSize(1024 * 1024);
        container.setMaxSessionIdleTimeout(60000L);
        return container;
    }

    @Bean
    public SubscriptionRegistry subscriptionRegistry() {
        return new DefaultSubscriptionRegistry();
    }
}

