package org.hswebframework.web.socket.starter;

import org.hswebframework.web.authorization.token.UserTokenManager;
import org.hswebframework.web.concurrent.counter.CounterManager;
import org.hswebframework.web.message.Messager;
import org.hswebframework.web.socket.WebSocketSessionListener;
import org.hswebframework.web.socket.authorize.AuthorizeCommandProcessor;
import org.hswebframework.web.socket.authorize.SessionIdWebSocketTokenParser;
import org.hswebframework.web.socket.authorize.WebSocketTokenParser;
import org.hswebframework.web.socket.authorize.XAccessTokenParser;
import org.hswebframework.web.socket.handler.CommandWebSocketMessageDispatcher;
import org.hswebframework.web.socket.message.DefaultWebSocketMessager;
import org.hswebframework.web.socket.message.WebSocketMessager;
import org.hswebframework.web.socket.processor.DefaultCommandProcessorContainer;
import org.hswebframework.web.socket.processor.CommandProcessor;
import org.hswebframework.web.socket.processor.CommandProcessorContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.WebSocketConfigurationSupport;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import java.util.List;

/**
 * @author zhouhao
 */
@Configuration
public class CommandWebSocketAutoConfiguration {

    @Bean
    public SessionIdWebSocketTokenParser sessionIdWebSocketTokenParser() {
        return new SessionIdWebSocketTokenParser();
    }

    @Bean
    public XAccessTokenParser xAccessTokenParser() {
        return new XAccessTokenParser();
    }

    @Bean
    @ConditionalOnBean(UserTokenManager.class)
    public AuthorizeCommandProcessor authorizeCommandProcessor(UserTokenManager userTokenManager) {
        return new AuthorizeCommandProcessor(userTokenManager);
    }

    @Configuration
    @ConditionalOnMissingBean(CommandProcessorContainer.class)
    public static class WebSocketProcessorContainerConfiguration {
        @Autowired(required = false)
        private List<CommandProcessor> commandProcessors;

        @Bean(destroyMethod = "destroy")
        public DefaultCommandProcessorContainer defaultWebSocketProcessorContainer() {
            DefaultCommandProcessorContainer container = new DefaultCommandProcessorContainer();
            if (commandProcessors != null) {
                commandProcessors.forEach(container::install);
            }
            return container;
        }
    }

    @Configuration
    @ConditionalOnBean(Messager.class)
    @ConditionalOnMissingBean(WebSocketMessager.class)
    public static class WebSocketMessagerConfiguration {
        @Autowired(required = false)
        private CounterManager counterManager;

        @Bean
        public WebSocketMessager webSocketMessager(Messager messager) {
            return new DefaultWebSocketMessager(messager, counterManager);
        }
    }

    @Configuration
    @ConfigurationProperties(prefix = "hsweb.websocket")
    public static class HandlerConfigruation extends WebSocketConfigurationSupport {
        private String[] allowedOrigins;

        public void setAllowedOrigins(String[] allowedOrigins) {
            this.allowedOrigins = allowedOrigins;
        }

        @Autowired(required = false)
        private UserTokenManager userTokenManager;

        @Autowired(required = false)
        private List<WebSocketSessionListener> webSocketSessionListeners;

        @Autowired(required = false)
        private List<WebSocketTokenParser> webSocketTokenParsers;

        @Autowired
        private CommandProcessorContainer commandProcessorContainer;

        @Override
        protected void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            CommandWebSocketMessageDispatcher dispatcher = new CommandWebSocketMessageDispatcher();
            dispatcher.setProcessorContainer(commandProcessorContainer);
            dispatcher.setUserTokenManager(userTokenManager);
            dispatcher.setWebSocketSessionListeners(webSocketSessionListeners);
            dispatcher.setTokenParsers(webSocketTokenParsers);
            registry.addHandler(dispatcher, "/sockjs")
                    .setAllowedOrigins(allowedOrigins)
                    .withSockJS()
                    .setSessionCookieNeeded(true);
            registry.addHandler(dispatcher, "/socket")
                    .setAllowedOrigins(allowedOrigins);
        }
    }

}

@@ -1644,16 +1644,105 @@
 egistry;
+%0Aimport org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
 %0A%0Aimport
@@ -3398,32 +3398,440 @@
        %7D%0A    %7D%0A%0A
+    @Bean%0A    @ConfigurationProperties(prefix = %22hsweb.websocket%22)%0A    public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() %7B%0A        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();%0A        container.setMaxTextMessageBufferSize(10_1024_1024);%0A        container.setMaxBinaryMessageBufferSize(10_1024_1024);%0A        return container;%0A    %7D%0A%0A
     @Configurati

add websocket config property : hsweb.websocket