package pl.nn44.battleship.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;
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 pl.nn44.battleship.controller.GameController;
import pl.nn44.battleship.model.Cell;
import pl.nn44.battleship.model.Coord;
import pl.nn44.battleship.model.Grid;
import pl.nn44.battleship.service.locker.Locker;
import pl.nn44.battleship.service.locker.LockerImpl;
import pl.nn44.battleship.service.serializer.CellSerializer;
import pl.nn44.battleship.service.serializer.CoordSerializer;
import pl.nn44.battleship.service.serializer.GridSerializer;
import pl.nn44.battleship.service.serializer.Serializer;
import pl.nn44.battleship.service.verifier.FleetVerifier;
import pl.nn44.battleship.service.verifier.FleetVerifierFactory;
import pl.nn44.battleship.util.id.BigIdGenerator;
import pl.nn44.battleship.util.id.IdGenerator;

import java.security.SecureRandom;
import java.util.List;
import java.util.Random;

@Configuration
@EnableWebSocket
@EnableConfigurationProperties
class GameConfiguration implements WebSocketConfigurer {

    final GameProperties gm;

    @Autowired
    GameConfiguration(GameProperties gm) {
        Assert.notNull(gm);
        this.gm = gm;
    }

    @Bean
    GameController webSocketController() {

        Random random = new SecureRandom();
        Locker locker = new LockerImpl(gm.getImpl().getLocksNo());
        IdGenerator idGenerator = new BigIdGenerator(random, gm.getImpl().getIdLen());
        FleetVerifier fleetVerifier = FleetVerifierFactory.forTypeFromGm(gm);
        Serializer<Grid, String> gridSerializer = new GridSerializer(gm);
        Serializer<Coord, String> coordSerializer = new CoordSerializer();
        Serializer<List<Cell>, String> cellSerializer = new CellSerializer();

        return new GameController(
                random,
                locker,
                idGenerator,
                fleetVerifier,
                gridSerializer,
                coordSerializer,
                cellSerializer);
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketController(), "/ws").setAllowedOrigins("*");
    }
}

@@ -36,16 +36,196 @@
 ation;%0A%0A
+import org.eclipse.jetty.websocket.api.WebSocketBehavior;%0Aimport org.eclipse.jetty.websocket.api.WebSocketPolicy;%0Aimport org.eclipse.jetty.websocket.server.WebSocketServerFactory;%0A
 import o
@@ -742,24 +742,245 @@
 erRegistry;%0A
+import org.springframework.web.socket.server.HandshakeHandler;%0Aimport org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy;%0Aimport org.springframework.web.socket.server.support.DefaultHandshakeHandler;%0A
 import pl.nn
@@ -1781,16 +1781,54 @@
 .Random;
+%0Aimport java.util.concurrent.TimeUnit;
 %0A%0A@Confi
@@ -1884,16 +1884,108 @@
 perties%0A
+// http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html%0A
 class Ga
@@ -2981,24 +2981,407 @@
 er);%0A    %7D%0A%0A
+    @Bean%0A    HandshakeHandler handshakeHandler() %7B%0A        WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);%0A        policy.setIdleTimeout(TimeUnit.MINUTES.toMillis(5L));%0A%0A        return new DefaultHandshakeHandler(%0A                new JettyRequestUpgradeStrategy(%0A                        new WebSocketServerFactory(policy)%0A                )%0A        );%0A    %7D%0A%0A
     @Overrid
@@ -3518,16 +3518,33 @@
 , %22/ws%22)
+%0A                
 .setAllo
@@ -3558,16 +3558,73 @@
 ins(%22*%22)
+%0A                .setHandshakeHandler(handshakeHandler())
 ;%0A    %7D%0A

customize websocket timeout