/*
 * Copyright Avaya Inc., All Rights Reserved.
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Avaya Inc.
 *
 * The copyright notice above does not evidence any actual or intended
 * publication of such source code.
 *
 * Some third-party source code components may have been modified from their
 * original versions by Avaya Inc.
 *
 * The modifications are Copyright Avaya Inc., All Rights Reserved.
 */

package com.avaya.oceanalytics.openinterface.websocketclient.websocket;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

/**
 * Test cases for the {@link WebSocketRtdProvider} class.
 *
 * @author Ivan Kovalev
 *
 */

public class TestWebSocketRtdProvider {


    private static final String ENDPOINT_URL = "127.0.0.1/advertime";

    @Mock
    private RealtimeDataHandler realtimeDataHandler;
    @Mock
    private ListenableFuture<WebSocketSession> webSessionFuture;
    @Mock
    private StandardWebSocketClient socket;

    private WebSocketRtdProvider rtdProvider;

    @Before
    public void setup() throws Exception {
        MockitoAnnotations.initMocks(this);
        rtdProvider = new WebSocketRtdProvider(null);
        setPrivateFinalField("socket", socket);
    }

    @Test(expected = RealtimeDataProviderException.class)
    public void testSend_withSessionEqualsNull() {
        rtdProvider.send("message");
    }

    @Test
    public void testConnect() throws ExecutionException, InterruptedException, TimeoutException {
        when(socket.doHandshake(any(DelegatingWebsocketHandler.class),eq(ENDPOINT_URL))).thenReturn(webSessionFuture);
        rtdProvider.connect(ENDPOINT_URL,realtimeDataHandler);
        verify(webSessionFuture,times(1)).get(10L, TimeUnit.MINUTES);
    }

    private void setPrivateFinalField(String fieldName, Object value) throws Exception {
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        Field targetField = WebSocketRtdProvider.class.getDeclaredField(fieldName);
        modifiersField.setInt(targetField, targetField.getModifiers() & ~Modifier.FINAL);
        targetField.setAccessible(true);
        targetField.set(rtdProvider, value);
    }
}
