/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.tomcat.websocket;

import java.net.URI;
import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletContextEvent;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.EndpointConfig;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;

import org.junit.Assert;
import org.junit.Test;


import org.apache.catalina.Context;
import org.apache.catalina.servlets.DefaultServlet;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEndpoint;
import org.apache.tomcat.websocket.server.Constants;
import org.apache.tomcat.websocket.server.WsContextListener;

public class TestWsSubprotocols extends WebSocketBaseTest {

    @Test
    public void testWsSubprotocols() throws Exception {
        Tomcat tomcat = getTomcatInstance();
        // No file system docBase required
        Context ctx = tomcat.addContext("", null);
        ctx.addApplicationListener(Config.class.getName());

        Tomcat.addServlet(ctx, "default", new DefaultServlet());
        ctx.addServletMappingDecoded("/", "default");

        tomcat.start();

        WebSocketContainer wsContainer = ContainerProvider
                .getWebSocketContainer();

        tomcat.start();

        Session wsSession = wsContainer.connectToServer(
                TesterProgrammaticEndpoint.class, ClientEndpointConfig.Builder
                        .create().preferredSubprotocols(Arrays.asList("sp3"))
                        .build(), new URI("ws://localhost:" + getPort()
                        + SubProtocolsEndpoint.PATH_BASIC));

        Assert.assertTrue(wsSession.isOpen());
        if (wsSession.getNegotiatedSubprotocol() != null) {
            Assert.assertTrue(wsSession.getNegotiatedSubprotocol().isEmpty());
        }
        wsSession.close();
        SubProtocolsEndpoint.recycle();

        wsSession = wsContainer.connectToServer(
                TesterProgrammaticEndpoint.class, ClientEndpointConfig.Builder
                        .create().preferredSubprotocols(Arrays.asList("sp2"))
                        .build(), new URI("ws://localhost:" + getPort()
                        + SubProtocolsEndpoint.PATH_BASIC));

        Assert.assertTrue(wsSession.isOpen());
        Assert.assertEquals("sp2", wsSession.getNegotiatedSubprotocol());
        // Client thread might move faster than server. Wait for upto 5s for the
        // subProtocols to be set
        int count = 0;
        while (count < 50 && SubProtocolsEndpoint.subprotocols == null) {
            count++;
            Thread.sleep(100);
        }
        Assert.assertNotNull(SubProtocolsEndpoint.subprotocols);
        Assert.assertArrayEquals(new String[]{"sp1","sp2"},
                SubProtocolsEndpoint.subprotocols.toArray(new String[2]));
        wsSession.close();
        SubProtocolsEndpoint.recycle();
    }

    @ServerEndpoint(value = "/echo", subprotocols = {"sp1","sp2"})
    public static class SubProtocolsEndpoint {
        public static String PATH_BASIC = "/echo";
        public static volatile List<String> subprotocols;

        @OnOpen
        public void processOpen(@SuppressWarnings("unused") Session session,
                EndpointConfig  epc) {
            subprotocols = ((ServerEndpointConfig)epc).getSubprotocols();
        }

        public static void recycle() {
            subprotocols = null;
        }

    }

    public static class Config extends WsContextListener {
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            super.contextInitialized(sce);
            ServerContainer sc = (ServerContainer) sce.getServletContext()
                    .getAttribute(Constants.
                            SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
            try {
                sc.addEndpoint(SubProtocolsEndpoint.class);
            } catch (DeploymentException e) {
                throw new IllegalStateException(e);
            }
        }
    }
}
