// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.media.router.caf;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import com.google.android.gms.cast.ApplicationMetadata;
import com.google.android.gms.cast.CastDevice;
import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.common.api.Status;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;

import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.media.router.CastSessionUtil;
import org.chromium.chrome.browser.media.router.ClientRecord;
import org.chromium.chrome.browser.media.router.JSONTestUtils.JSONObjectLike;
import org.chromium.chrome.browser.media.router.JSONTestUtils.JSONStringLike;
import org.chromium.chrome.browser.media.router.MediaSink;
import org.chromium.chrome.browser.media.router.caf.CafMessageHandler.RequestRecord;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Robolectric tests for CastSession.
 */
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class CafMessageHandlerTest {
    private static final String TAG = "MediaRouter";

    private static final String SESSION_ID = "SESSION_ID";
    private static final String INVALID_SESSION_ID = "INVALID_SESSION_ID";
    private static final String CLIENT_ID1 = "client-id-1";
    private static final String CLIENT_ID2 = "client-id-2";
    private static final String INVALID_CLIENT_ID = "xxxxxxxxxxxxxxxxx";
    private static final String NAMESPACE1 = "namespace1";
    private static final String NAMESPACE2 = "namespace2";
    private static final String MEDIA_NAMESPACE = CastSessionUtil.MEDIA_NAMESPACE;
    private static final int SEQUENCE_NUMBER1 = 1;
    private static final int SEQUENCE_NUMBER2 = 2;
    private static final int REQUEST_ID1 = 1;
    private static final int REQUEST_ID2 = 2;
    private static final int VOID_SEQUENCE_NUMBER = CafMessageHandler.VOID_SEQUENCE_NUMBER;
    private CafMediaRouteProvider mRouteProvider;
    @Mock
    private CastSession mSession;
    @Mock
    private CastSessionController mSessionController;
    private ClientRecord mClientRecord1;
    private ClientRecord mClientRecord2;
    private Map<String, ClientRecord> mClientRecordMap;
    private CafMessageHandler mMessageHandler;
    private int mNumStopApplicationCalled;

    private interface CheckedRunnable { void run() throws Exception; }

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mRouteProvider = mock(CafMediaRouteProvider.class);
        mClientRecord1 =
                new ClientRecord("route-id-1", CLIENT_ID1, "app-id", "auto-join", "origin", 1);
        mClientRecord2 =
                new ClientRecord("route-id-2", CLIENT_ID2, "app-id", "auto-join", "origin2", 1);

        mMessageHandler = spy(new CafMessageHandler(mRouteProvider, mSessionController));

        doReturn(SESSION_ID).when(mSessionController).getSessionId();
        doReturn(true)
                .when(mMessageHandler)
                .sendStringCastMessage(anyString(), anyString(), anyString(), anyInt());
        doReturn(mSession).when(mSessionController).getSession();
        doReturn(true).when(mSessionController).isConnected();
        doReturn(SESSION_ID).when(mSessionController).getSessionId();

        mClientRecordMap = new HashMap<>();

        mClientRecordMap.put(CLIENT_ID1, mClientRecord1);
        mClientRecordMap.put(CLIENT_ID2, mClientRecord2);
        doReturn(mClientRecordMap).when(mRouteProvider).getClientIdToRecords();
        doNothing().when(mRouteProvider).sendMessageToClient(anyString(), anyString());
    }

    void setUpForAppMessageTest() throws JSONException {
        List<String> namespaces = new ArrayList<String>();
        namespaces.add(NAMESPACE1);
        doReturn(namespaces).when(mSessionController).getNamespaces();
        doReturn(true)
                .when(mMessageHandler)
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testOnSessionStarted() {
        doReturn("session_message").when(mMessageHandler).buildSessionMessage();
        // The call in setUp() actually only sets the session. This call will notify the clients
        // that have sent "client_connect"
        mClientRecord1.isConnected = true;

        mMessageHandler.onSessionStarted();

        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        CLIENT_ID1, "new_session", "session_message", VOID_SEQUENCE_NUMBER);
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(eq(CLIENT_ID2), anyString(), anyString(), anyInt());
    }

    @Test
    public void testHandleClientConnectMessage_sessionConnected() throws JSONException {
        doReturn("session_message").when(mMessageHandler).buildSessionMessage();
        mClientRecord1.isConnected = false;
        JSONObject message = new JSONObject();
        message.put("type", "client_connect");
        message.put("clientId", mClientRecord1.clientId);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        assertTrue(mClientRecord1.isConnected);
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(mClientRecord1.clientId, "new_session",
                        "session_message", VOID_SEQUENCE_NUMBER);
        verify(mRouteProvider).flushPendingMessagesToClient(mClientRecord1);
    }

    @Test
    public void testHandleClientConnectMessage_sessionNotConnected() throws JSONException {
        doReturn("session_message").when(mMessageHandler).buildSessionMessage();
        doReturn(false).when(mSessionController).isConnected();
        mClientRecord1.isConnected = false;
        JSONObject message = new JSONObject();
        message.put("type", "client_connect");
        message.put("clientId", mClientRecord1.clientId);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        assertTrue(mClientRecord1.isConnected);
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        verify(mRouteProvider).flushPendingMessagesToClient(mClientRecord1);
    }

    @Test
    public void testHandleClientConnectMessage_noClientRecord() throws JSONException {
        doReturn("session_message").when(mMessageHandler).buildSessionMessage();
        JSONObject message = new JSONObject();
        message.put("type", "client_connect");
        message.put("clientId", "other-client-id");

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        verify(mRouteProvider, never()).flushPendingMessagesToClient(any(ClientRecord.class));
    }

    @Test
    public void testHandleClientConnectMessage_noClientId() throws JSONException {
        doReturn("session_message").when(mMessageHandler).buildSessionMessage();
        JSONObject message = new JSONObject();
        message.put("type", "client_connect");

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        verify(mRouteProvider, never()).flushPendingMessagesToClient(any(ClientRecord.class));
    }

    @Test
    public void testHandleClientDisconnectMessage() throws JSONException {
        JSONObject message = new JSONObject();
        message.put("type", "client_disconnect");
        message.put("clientId", mClientRecord1.clientId);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider).removeRoute("route-id-1", null);
    }

    @Test
    public void testHandleClientDisconnectMessage_noClientRecord() throws JSONException {
        JSONObject message = new JSONObject();
        message.put("type", "client_disconnect");
        message.put("clientId", "other-client-id");

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider, never()).removeRoute(anyString(), anyString());
    }

    @Test
    public void testHandleClientDisconnectMessage_noClientId() throws JSONException {
        JSONObject message = new JSONObject();
        message.put("type", "client_disconnect");

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider, never()).removeRoute(anyString(), anyString());
    }

    @Test
    public void testHandleClientLeaveSessionMessage() throws JSONException {
        JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345);
        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider)
                .sendMessageToClient(eq(mClientRecord1.clientId), messageCaptor.capture());
        JSONObject capturedMessage = new JSONObject(messageCaptor.getValue());
        verifySimpleSessionMessage(
                capturedMessage, "leave_session", 12345, mClientRecord1.clientId);
    }

    @Test
    public void testHandleClientLeaveSessionMessage_noSequenceNumber() throws JSONException {
        JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345);
        message.remove("sequenceNumber");
        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider)
                .sendMessageToClient(eq(mClientRecord1.clientId), messageCaptor.capture());
        JSONObject capturedMessage = new JSONObject(messageCaptor.getValue());
        verifySimpleSessionMessage(
                capturedMessage, "leave_session", VOID_SEQUENCE_NUMBER, mClientRecord1.clientId);
    }

    @Test
    public void testHandleClientLeaveSessionMessage_noClientRecord() throws JSONException {
        JSONObject message = buildLeaveSessionMessage("other-client-id", SESSION_ID, 12345);

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString());
    }

    @Test
    public void testHandleClientLeaveSessionMessage_wrongSessionId() throws JSONException {
        JSONObject message =
                buildLeaveSessionMessage(mClientRecord1.clientId, "other-session-id", 12345);

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString());
    }

    @Test
    public void testHandleClientLeaveSessionMessage_sessionNotConnected() throws JSONException {
        doReturn(false).when(mSessionController).isConnected();
        JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345);

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString());
    }

    @Test
    public void testHandleClientLeaveSessionMessage_noClientId() throws JSONException {
        JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345);
        message.remove("clientId");

        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));

        verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString());
    }

    @Test
    public void testHandleClientLeaveSessionMessage_removeRoutes_tabAndOriginScoped()
            throws JSONException {
        mClientRecordMap.clear();

        prepareClientRecord(
                "route-id-1", "client-id-1", "app-id", "tab_and_origin_scoped", "origin", 1);
        prepareClientRecord("route-id-2", "client-id-2", "app-id", "auto-join", "origin", 1);
        prepareClientRecord("route-id-3", "client-id-3", "app-id", "auto-join", "origin2", 1);
        prepareClientRecord("route-id-4", "client-id-4", "app-id", "auto-join", "origin", 2);

        JSONObject message = buildLeaveSessionMessage("client-id-1", SESSION_ID, 12345);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        // Only routes with same origin and tab ID will be removed.
        verify(mRouteProvider).removeRoute("route-id-1", null);
        verify(mRouteProvider).removeRoute("route-id-2", null);
        verify(mRouteProvider, never()).removeRoute("route-id-3", null);
        verify(mRouteProvider, never()).removeRoute("route-id-4", null);
    }

    @Test
    public void testHandleClientLeaveSessionMessage_removeRoutes_originScoped()
            throws JSONException {
        prepareClientRecord("route-id-1", "client-id-1", "app-id", "origin_scoped", "origin", 1);
        prepareClientRecord("route-id-2", "client-id-2", "app-id", "auto-join", "origin", 1);
        prepareClientRecord("route-id-3", "client-id-3", "app-id", "auto-join", "origin2", 1);
        prepareClientRecord("route-id-4", "client-id-4", "app-id", "auto-join", "origin", 2);

        JSONObject message = buildLeaveSessionMessage("client-id-1", SESSION_ID, 12345);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        // Only routes with same origin will be removed.
        verify(mRouteProvider).removeRoute("route-id-1", null);
        verify(mRouteProvider).removeRoute("route-id-2", null);
        verify(mRouteProvider, never()).removeRoute("route-id-3", null);
        verify(mRouteProvider).removeRoute("route-id-4", null);
    }

    @Test
    public void testHandleClientLeaveSessionMessage_removeRoutes_otherScoped()
            throws JSONException {
        prepareClientRecord("route-id-1", "client-id-1", "app-id", "other_scoped", "origin", 1);
        prepareClientRecord("route-id-2", "client-id-2", "app-id", "auto-join", "origin", 1);
        prepareClientRecord("route-id-3", "client-id-3", "app-id", "auto-join", "origin2", 1);
        prepareClientRecord("route-id-4", "client-id-4", "app-id", "auto-join", "origin", 2);

        JSONObject message = buildLeaveSessionMessage("client-id-1", SESSION_ID, 12345);

        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

        // No route should be removed.
        verify(mRouteProvider, never()).removeRoute(anyString(), anyString());
    }

    @Test
    public void testHandleSessionMessageOfV2MessageType() throws JSONException {
        doReturn(true).when(mMessageHandler).handleCastV2MessageFromClient(any(JSONObject.class));

        JSONObject message = new JSONObject();
        message.put("type", "v2_message");
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler).handleCastV2MessageFromClient(argThat(new JSONObjectLike(message)));
    }

    @Test
    public void testHandleSessionMessageOfAppMessageType() throws JSONException {
        doReturn(true).when(mMessageHandler).handleAppMessageFromClient(any(JSONObject.class));

        JSONObject message = new JSONObject();
        message.put("type", "app_message");
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler).handleAppMessageFromClient(argThat(new JSONObjectLike(message)));
    }

    @Test
    public void testHandleSessionMessageOfUnsupportedType() throws JSONException {
        doReturn(true).when(mMessageHandler).handleCastV2MessageFromClient(any(JSONObject.class));

        JSONObject message = new JSONObject();
        message.put("type", "unsupported");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never()).handleCastV2MessageFromClient(any(JSONObject.class));
        verify(mMessageHandler, never()).handleAppMessageFromClient(any(JSONObject.class));
    }

    @Test
    public void testCastV2MessageWithWrongTypeInnerMessage() throws JSONException {
        org.robolectric.shadows.ShadowLog.stream = System.out;
        JSONObject innerMessage = new JSONObject().put("type", "STOP");
        final JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        // Replace the inner JSON message with string.
        message.put("message", "wrong type inner message");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never()).handleStopMessage(anyString(), anyInt());
        verify(mMessageHandler, never())
                .handleVolumeMessage(any(JSONObject.class), anyString(), anyInt());
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testCastV2MessageOfStopType() throws JSONException {
        JSONObject innerMessage = new JSONObject().put("type", "STOP");
        JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler).handleStopMessage(eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testCastV2MessageofSetVolumeTypeShouldWait() throws Exception {
        doReturn(true).when(mSession).isMute();
        JSONObject innerMessage =
                new JSONObject()
                        .put("type", "SET_VOLUME")
                        .put("volume",
                                new JSONObject().put("level", (double) 1).put("muted", false));
        JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        JSONObject volumeMessage = innerMessage.getJSONObject("volume");
        verify(mSession).setMute(false);
        verify(mSession).setVolume(1.0);
        verify(mMessageHandler)
                .handleVolumeMessage(
                        argThat(new JSONObjectLike(innerMessage.getJSONObject("volume"))),
                        eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1));
        assertEquals(mMessageHandler.getVolumeRequestsForTest().size(), 1);
    }

    @Test
    public void testCastV2MessageofSetVolumeTypeShouldNotWait() throws Exception {
        doReturn(false).when(mSession).isMute();
        doReturn(1.0).when(mSession).getVolume();
        JSONObject innerMessage =
                new JSONObject()
                        .put("type", "SET_VOLUME")
                        .put("volume",
                                new JSONObject().put("level", (double) 1).put("muted", false));
        JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        JSONObject volumeMessage = innerMessage.getJSONObject("volume");
        verify(mSession, never()).setMute(anyBoolean());
        verify(mSession, never()).setVolume(anyDouble());
        verify(mMessageHandler)
                .handleVolumeMessage(
                        argThat(new JSONObjectLike(innerMessage.getJSONObject("volume"))),
                        eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1));
        assertEquals(mMessageHandler.getVolumeRequestsForTest().size(), 0);
    }

    @Test
    public void testCastV2MessageofSetVolumeTypeWithNullVolumeMessage() throws JSONException {
        JSONObject innerMessage = new JSONObject().put("type", "SET_VOLUME");
        final JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .handleVolumeMessage(any(JSONObject.class), anyString(), anyInt());
    }

    @Test
    public void testCastV2MessageofSetVolumeTypeWithWrongTypeVolumeMessage() throws JSONException {
        JSONObject innerMessage = new JSONObject()
                                          .put("type", "SET_VOLUME")
                                          .put("volume", "wrong type volume message");
        final JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .handleVolumeMessage(any(JSONObject.class), anyString(), anyInt());
    }

    @Test
    public void testCastV2MessageOfMediaMessageType() throws JSONException {
        doReturn(true)
                .when(mMessageHandler)
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
        for (String messageType : CafMessageHandler.getMediaMessageTypesForTest()) {
            // TODO(zqzhang): SET_VOLUME and STOP should not reach here?
            if ("MEDIA_SET_VOLUME".equals(messageType) || "STOP_MEDIA".equals(messageType)) {
                continue;
            }
            JSONObject innerMessage = new JSONObject().put("type", messageType);
            JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
            assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));

            JSONObject expected = new JSONObject();
            if (CafMessageHandler.getMediaOverloadedMessageTypesForTest().containsKey(
                        messageType)) {
                expected.put("type",
                        CafMessageHandler.getMediaOverloadedMessageTypesForTest().get(messageType));
            } else {
                expected.put("type", messageType);
            }
            verify(mMessageHandler)
                    .sendJsonCastMessage(argThat(new JSONObjectLike(expected)),
                            eq(CastSessionUtil.MEDIA_NAMESPACE), eq(CLIENT_ID1),
                            eq(SEQUENCE_NUMBER1));
        }
    }

    @Test
    public void testCastV2MessageWithNullSequenceNumber() throws JSONException {
        JSONObject innerMessage = new JSONObject().put("type", "STOP");
        JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
        message.remove("sequenceNumber");
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler).handleStopMessage(eq(CLIENT_ID1), eq(VOID_SEQUENCE_NUMBER));
    }

    @Test
    public void testHandleStopMessage() throws JSONException {
        InOrder inOrder = inOrder(mSessionController);
        assertEquals(0, mMessageHandler.getStopRequestsForTest().size());
        mMessageHandler.handleStopMessage(CLIENT_ID1, SEQUENCE_NUMBER1);
        assertEquals(1, mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).size(), 1);
        inOrder.verify(mSessionController).endSession();
        mMessageHandler.handleStopMessage(CLIENT_ID1, SEQUENCE_NUMBER2);
        assertEquals(2, mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).size(), 2);
        inOrder.verify(mSessionController).endSession();
    }

    @Test
    public void testAppMessageWithExistingNamespace() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler)
                .sendJsonCastMessage(argThat(new JSONObjectLike(actualMessage)), eq(NAMESPACE1),
                        eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testAppMessageWithNonexistingNamespace() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE2, actualMessage);
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithoutSequenceNumber() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.remove("sequenceNumber");
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler)
                .sendJsonCastMessage(argThat(new JSONObjectLike(actualMessage)), eq(NAMESPACE1),
                        eq(CLIENT_ID1), eq(VOID_SEQUENCE_NUMBER));
    }

    @Test
    public void testAppMessageWithNullSessionId() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.getJSONObject("message").remove("sessionId");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithWrongSessionId() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.getJSONObject("message").put("sessionId", INVALID_SESSION_ID);
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithNullActualMessage() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.getJSONObject("message").remove("message");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithStringMessage() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.getJSONObject("message").put("message", "string message");
        assertTrue(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
        verify(mMessageHandler)
                .sendStringCastMessage(
                        eq("string message"), eq(NAMESPACE1), eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testAppMessageWithNullAppMessage() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.remove("message");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithEmptyAppMessage() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.put("message", new JSONObject());
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithWrongTypeAppMessage() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.put("message", "wrong type app message");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithNullClient() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.remove("clientId");
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testAppMessageWithNonexistingClient() throws JSONException {
        setUpForAppMessageTest();

        JSONObject actualMessage = buildActualAppMessage();
        JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage);
        message.put("clientId", INVALID_CLIENT_ID);
        assertFalse(mMessageHandler.handleMessageFromClient(message.toString()));
        verify(mMessageHandler, never())
                .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt());
    }

    @Test
    public void testSendJsonCastMessage() throws JSONException {
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        JSONObject message = buildJsonCastMessage("message");
        assertTrue(mMessageHandler.sendJsonCastMessage(
                message, NAMESPACE1, CLIENT_ID1, SEQUENCE_NUMBER1));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        verify(mMessageHandler)
                .sendStringCastMessage(
                        argThat(new JSONStringLike(message)), anyString(), anyString(), anyInt());
    }

    @Test
    public void testSendJsonCastMessageWhileDisconnected() throws JSONException {
        doReturn(false).when(mSessionController).isConnected();

        JSONObject message = buildJsonCastMessage("message");
        assertFalse(mMessageHandler.sendJsonCastMessage(
                message, NAMESPACE1, CLIENT_ID1, SEQUENCE_NUMBER1));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        verify(mMessageHandler, never())
                .sendStringCastMessage(anyString(), anyString(), anyString(), anyInt());
    }

    @Test
    public void testSendJsonCastMessageWithInvalidSequenceNumber() throws JSONException {
        JSONObject message = buildJsonCastMessage("message");
        assertTrue(mMessageHandler.sendJsonCastMessage(
                message, NAMESPACE1, CLIENT_ID1, VOID_SEQUENCE_NUMBER));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        verify(mMessageHandler)
                .sendStringCastMessage(
                        argThat(new JSONStringLike(message)), anyString(), anyString(), anyInt());
    }

    @Test
    public void testSendJsonCastMessageWithNullRequestId() throws JSONException {
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        JSONObject message = buildJsonCastMessage("message");
        message.remove("requestId");
        assertTrue(mMessageHandler.sendJsonCastMessage(
                message, NAMESPACE1, CLIENT_ID1, SEQUENCE_NUMBER1));
        assertTrue(message.has("requestId"));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        verify(mMessageHandler)
                .sendStringCastMessage(
                        argThat(new JSONStringLike(message)), anyString(), anyString(), anyInt());
    }

    @Test
    public void testOnMessageReceivedWithExistingRequestId() throws JSONException {
        doNothing()
                .when(mMessageHandler)
                .onAppMessage(anyString(), anyString(), any(RequestRecord.class));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1);
        mMessageHandler.getRequestsForTest().append(REQUEST_ID1, request);
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        JSONObject message = new JSONObject();
        message.put("requestId", REQUEST_ID1);
        mMessageHandler.onMessageReceived(NAMESPACE1, message.toString());
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        verify(mMessageHandler).onAppMessage(eq(message.toString()), eq(NAMESPACE1), eq(request));
    }

    @Test
    public void testOnMessageReceivedWithNonexistingRequestId() throws JSONException {
        doNothing()
                .when(mMessageHandler)
                .onAppMessage(anyString(), anyString(), any(RequestRecord.class));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1);
        mMessageHandler.getRequestsForTest().append(REQUEST_ID1, request);
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        JSONObject message = new JSONObject();
        message.put("requestId", REQUEST_ID2);
        mMessageHandler.onMessageReceived(NAMESPACE1, message.toString());
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        verify(mMessageHandler)
                .onAppMessage(eq(message.toString()), eq(NAMESPACE1), (RequestRecord) isNull());
    }

    @Test
    public void testOnMessageReceivedWithoutRequestId() throws JSONException {
        doNothing()
                .when(mMessageHandler)
                .onAppMessage(anyString(), anyString(), any(RequestRecord.class));
        assertEquals(mMessageHandler.getRequestsForTest().size(), 0);
        RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1);
        mMessageHandler.getRequestsForTest().append(REQUEST_ID1, request);
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        JSONObject message = new JSONObject();
        mMessageHandler.onMessageReceived(NAMESPACE1, message.toString());
        assertEquals(mMessageHandler.getRequestsForTest().size(), 1);
        verify(mMessageHandler)
                .onAppMessage(eq(message.toString()), eq(NAMESPACE1), (RequestRecord) isNull());
    }

    @Test
    public void testOnMessageReceivedOfMediaNamespace() throws JSONException {
        doNothing().when(mMessageHandler).onMediaMessage(anyString(), any(RequestRecord.class));
        mMessageHandler.onMessageReceived(MEDIA_NAMESPACE, "anymessage");
        verify(mMessageHandler).onMediaMessage(eq("anymessage"), (RequestRecord) isNull());
    }

    @Test
    public void testOnMediaMessageOfMediaStatusTypeWithRequestRecord() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        doReturn(true).when(mMessageHandler).isMediaStatusMessage(anyString());
        RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1);
        mMessageHandler.onMediaMessage("anymessage", request);
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"),
                        eq(VOID_SEQUENCE_NUMBER));
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(eq(CLIENT_ID2), eq("v2_message"), eq("anymessage"),
                        eq(VOID_SEQUENCE_NUMBER));
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testOnMediaMessageOfMediaStatusTypeWithNullRequestRecord() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        doReturn(true).when(mMessageHandler).isMediaStatusMessage(anyString());
        mMessageHandler.onMediaMessage("anymessage", null);
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"),
                        eq(VOID_SEQUENCE_NUMBER));
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(eq(CLIENT_ID2), eq("v2_message"), eq("anymessage"),
                        eq(VOID_SEQUENCE_NUMBER));
    }

    @Test
    public void testOnMediaMessageOfNonMediaStatusTypeWithRequestRecord() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        doReturn(false).when(mMessageHandler).isMediaStatusMessage(anyString());
        RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1);
        mMessageHandler.onMediaMessage("anymessage", request);
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(
                        anyString(), anyString(), anyString(), eq(VOID_SEQUENCE_NUMBER));
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testOnMediaMessageOfNonMediaStatusTypeWithNullRequestRecord() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        doReturn(false).when(mMessageHandler).isMediaStatusMessage(anyString());
        mMessageHandler.onMediaMessage("anymessage", null);
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(
                        anyString(), anyString(), anyString(), eq(VOID_SEQUENCE_NUMBER));
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
    }

    @Test
    public void testOnAppMessageWithRequestRecord() throws JSONException {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1);
        mMessageHandler.onAppMessage("anyMessage", NAMESPACE1, request);
        JSONObject expected = new JSONObject();
        expected.put("sessionId", SESSION_ID);
        expected.put("namespaceName", NAMESPACE1);
        expected.put("message", "anyMessage");
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(eq(CLIENT_ID1), eq("app_message"),
                        argThat(new JSONStringLike(expected)), eq(SEQUENCE_NUMBER1));
        verify(mMessageHandler, never()).broadcastClientMessage(anyString(), anyString());
    }

    @Test
    public void testOnAppMessageWithNullRequestRecord() throws JSONException {
        doNothing().when(mMessageHandler).broadcastClientMessage(anyString(), anyString());
        mMessageHandler.onAppMessage("anyMessage", NAMESPACE1, null);
        JSONObject expected = new JSONObject();
        expected.put("sessionId", SESSION_ID);
        expected.put("namespaceName", NAMESPACE1);
        expected.put("message", "anyMessage");
        verify(mMessageHandler, never())
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        verify(mMessageHandler)
                .broadcastClientMessage(eq("app_message"), argThat(new JSONStringLike(expected)));
    }

    @Test
    public void testOnSessionEnded() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        assertEquals(0, mMessageHandler.getStopRequestsForTest().size());
        mMessageHandler.getStopRequestsForTest().put(CLIENT_ID1, new ArrayDeque<Integer>());
        mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).add(SEQUENCE_NUMBER1);
        mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).add(SEQUENCE_NUMBER2);
        assertEquals(1, mMessageHandler.getStopRequestsForTest().size());
        assertEquals(2, mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).size());

        mMessageHandler.onSessionEnded();
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        eq(CLIENT_ID1), eq("remove_session"), eq(SESSION_ID), eq(SEQUENCE_NUMBER1));
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        eq(CLIENT_ID1), eq("remove_session"), eq(SESSION_ID), eq(SEQUENCE_NUMBER2));
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(eq(CLIENT_ID2), eq("remove_session"), eq(SESSION_ID),
                        eq(VOID_SEQUENCE_NUMBER));
    }

    @Test
    public void testOnVolumeChanged() {
        doNothing().when(mMessageHandler).onVolumeChanged(anyString(), anyInt());
        assertEquals(0, mMessageHandler.getVolumeRequestsForTest().size());
        mMessageHandler.getVolumeRequestsForTest().add(
                new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1));
        assertEquals(1, mMessageHandler.getVolumeRequestsForTest().size());

        mMessageHandler.onVolumeChanged();
        verify(mMessageHandler).onVolumeChanged(CLIENT_ID1, SEQUENCE_NUMBER1);
        assertEquals(0, mMessageHandler.getVolumeRequestsForTest().size());
    }

    @Test
    public void testOnVolumeChangedWithEmptyVolumeRequests() {
        mMessageHandler.onVolumeChanged();
        verify(mMessageHandler, never()).onVolumeChanged(eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testOnVolumeChangedForClient() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        mMessageHandler.onVolumeChanged(CLIENT_ID1, SEQUENCE_NUMBER1);
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        eq(CLIENT_ID1), eq("v2_message"), (String) isNull(), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testOnAppMessageSent() {
        Status mockResult = mock(Status.class);
        doReturn(true).when(mockResult).isSuccess();
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        mMessageHandler.onSendAppMessageResult(mockResult, CLIENT_ID1, SEQUENCE_NUMBER1);
        verify(mMessageHandler)
                .sendEnclosedMessageToClient(
                        eq(CLIENT_ID1), eq("app_message"), (String) isNull(), eq(SEQUENCE_NUMBER1));
    }

    @Test
    public void testSendEnclosedMessageToClient() throws JSONException {
        String message = "dontcare_message1";
        doReturn(message)
                .when(mMessageHandler)
                .buildEnclosedClientMessage(anyString(), anyString(), anyString(), anyInt());
        mMessageHandler.sendEnclosedMessageToClient(
                CLIENT_ID1, "anytype", "dontcare_message2", SEQUENCE_NUMBER1);

        verify(mRouteProvider).sendMessageToClient(eq(CLIENT_ID1), eq(message));
    }

    @Test
    public void testBroadcastClientMessage() {
        doNothing()
                .when(mMessageHandler)
                .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt());
        mMessageHandler.broadcastClientMessage("anytype", "anymessage");
        for (String clientId : mRouteProvider.getClientIdToRecords().keySet()) {
            verify(mMessageHandler)
                    .sendEnclosedMessageToClient(eq(clientId), eq("anytype"), eq("anymessage"),
                            eq(VOID_SEQUENCE_NUMBER));
        }
    }

    @Test
    public void testSendReceiverActionToClient() throws JSONException {
        MediaSink sink = mock(MediaSink.class);
        doReturn("sink-id").when(sink).getId();
        doReturn("sink-name").when(sink).getName();
        doReturn(Arrays.asList("audio_in", "audio_out", "video_in", "video_out"))
                .when(mSessionController)
                .getCapabilities();

        mMessageHandler.sendReceiverActionToClient("route-id", sink, "client-id", "action");

        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
        verify(mRouteProvider).sendMessageToClient(eq("client-id"), messageCaptor.capture());
        JSONObject capturedMessage = new JSONObject(messageCaptor.getValue());
        assertEquals(capturedMessage.getString("type"), "receiver_action");
        assertEquals(capturedMessage.getInt("sequenceNumber"), VOID_SEQUENCE_NUMBER);
        assertEquals(capturedMessage.getInt("timeoutMillis"), 0);
        assertEquals(capturedMessage.getString("clientId"), "client-id");

        JSONObject receiverAction = capturedMessage.getJSONObject("message");
        assertEquals(receiverAction.getString("action"), "action");

        JSONObject receiverInfo = receiverAction.getJSONObject("receiver");
        assertEquals(receiverInfo.getString("label"), "sink-id");
        assertEquals(receiverInfo.getString("friendlyName"), "sink-name");
        assertFalse(receiverInfo.has("volume"));
        assertFalse(receiverInfo.has("isActiveInput"));
        assertFalse(receiverInfo.has("displayStatus"));
        assertEquals(receiverInfo.getString("receiverType"), "cast");

        JSONArray capabilities = receiverInfo.getJSONArray("capabilities");
        assertEquals(capabilities.getString(0), "audio_in");
        assertEquals(capabilities.getString(1), "audio_out");
        assertEquals(capabilities.getString(2), "video_in");
        assertEquals(capabilities.getString(3), "video_out");
    }

    @Test
    public void testBuildEnclosedClientMessageWithNullMessage() throws JSONException {
        String message = mMessageHandler.buildEnclosedClientMessage(
                "anytype", null, CLIENT_ID1, SEQUENCE_NUMBER1);
        JSONObject expected = new JSONObject();
        expected.put("type", "anytype");
        expected.put("sequenceNumber", SEQUENCE_NUMBER1);
        expected.put("timeoutMillis", 0);
        expected.put("clientId", CLIENT_ID1);
        expected.put("message", null);

        assertTrue("\nexpected: " + expected.toString() + ",\n  actual: " + message.toString(),
                new JSONObjectLike(expected).matches(new JSONObject(message)));
    }

    @Test
    public void testBuildEnclosedClientMessageOfRemoveSessionType() throws JSONException {
        String message = mMessageHandler.buildEnclosedClientMessage(
                "remove_session", SESSION_ID, CLIENT_ID1, SEQUENCE_NUMBER1);
        JSONObject expected = new JSONObject();
        expected.put("type", "remove_session");
        expected.put("sequenceNumber", SEQUENCE_NUMBER1);
        expected.put("timeoutMillis", 0);
        expected.put("clientId", CLIENT_ID1);
        expected.put("message", SESSION_ID);

        assertTrue("\nexpected: " + expected.toString() + ",\n  actual: " + message.toString(),
                new JSONObjectLike(expected).matches(new JSONObject(message)));
    }

    @Test
    public void testBuildEnclosedClientMessageOfDisconnectSessionType() throws JSONException {
        String message = mMessageHandler.buildEnclosedClientMessage(
                "disconnect_session", SESSION_ID, CLIENT_ID1, SEQUENCE_NUMBER1);
        JSONObject expected = new JSONObject();
        expected.put("type", "disconnect_session");
        expected.put("sequenceNumber", SEQUENCE_NUMBER1);
        expected.put("timeoutMillis", 0);
        expected.put("clientId", CLIENT_ID1);
        expected.put("message", SESSION_ID);

        assertTrue("\nexpected: " + expected.toString() + ",\n  actual: " + message.toString(),
                new JSONObjectLike(expected).matches(new JSONObject(message)));
    }

    @Test
    public void testBuildEnclosedClientMessageWithInnerMessage() throws JSONException {
        JSONObject innerMessage = buildSessionMessage(SESSION_ID);
        String message = mMessageHandler.buildEnclosedClientMessage(
                "anytype", innerMessage.toString(), CLIENT_ID1, SEQUENCE_NUMBER1);
        JSONObject expected = new JSONObject();
        expected.put("type", "anytype");
        expected.put("sequenceNumber", SEQUENCE_NUMBER1);
        expected.put("timeoutMillis", 0);
        expected.put("clientId", CLIENT_ID1);
        expected.put("message", innerMessage);

        assertTrue("\nexpected: " + expected.toString() + ",\n  actual: " + message.toString(),
                new JSONObjectLike(expected).matches(new JSONObject(message)));
    }

    @Test
    public void testBuildSessionMessage() throws JSONException {
        CastDevice castDevice = mock(CastDevice.class);
        doReturn("device-id").when(castDevice).getDeviceId();
        doReturn("CastDevice friendly name").when(castDevice).getFriendlyName();
        doReturn(castDevice).when(mSession).getCastDevice();
        ApplicationMetadata appMetadata = mock(ApplicationMetadata.class);
        doReturn("app-id").when(appMetadata).getApplicationId();
        doReturn(appMetadata).when(mSession).getApplicationMetadata();
        doReturn(1.0).when(mSession).getVolume();
        doReturn(false).when(mSession).isMute();
        doReturn("status text").when(mSession).getApplicationStatus();
        doReturn(1).when(mSession).getActiveInputState();
        doReturn(Arrays.asList("namespace-1", "namespace-2"))
                .when(mSessionController)
                .getNamespaces();
        doReturn(Arrays.asList("audio_in", "audio_out", "video_in", "video_out"))
                .when(mSessionController)
                .getCapabilities();

        JSONObject message = new JSONObject(mMessageHandler.buildSessionMessage());

        assertEquals(message.getString("sessionId"), SESSION_ID);
        assertEquals(message.getString("statusText"), "status text");
        assertEquals(message.getString("status"), "connected");
        assertEquals(message.getString("transportId"), "web-4");
        assertEquals(message.getString("appId"), "app-id");
        assertEquals(message.getString("displayName"), "CastDevice friendly name");

        JSONArray mediaArray = message.getJSONArray("media");

        assertEquals(mediaArray.length(), 0);

        JSONArray namespacesArray = message.getJSONArray("namespaces");
        assertEquals(namespacesArray.length(), 2);
        assertEquals(namespacesArray.getJSONObject(0).getString("name"), "namespace-1");
        assertEquals(namespacesArray.getJSONObject(1).getString("name"), "namespace-2");

        JSONObject receiverInfo = message.getJSONObject("receiver");
        assertEquals(receiverInfo.getString("label"), "device-id");
        assertEquals(receiverInfo.getString("friendlyName"), "CastDevice friendly name");
        assertEquals(receiverInfo.getInt("isActiveInput"), 1);
        assertEquals(receiverInfo.getString("receiverType"), "cast");
        assertFalse(receiverInfo.has("displayStatus"));

        JSONArray capabilities = receiverInfo.getJSONArray("capabilities");
        assertEquals(capabilities.getString(0), "audio_in");
        assertEquals(capabilities.getString(1), "audio_out");
        assertEquals(capabilities.getString(2), "video_in");
        assertEquals(capabilities.getString(3), "video_out");

        JSONObject volume = receiverInfo.getJSONObject("volume");
        assertEquals(volume.getDouble("level"), 1.0, 1e-6);
        assertFalse(volume.getBoolean("muted"));
    }

    @Test
    public void testBuildSessionMessage_sessionDisconnected() {
        doReturn(false).when(mSessionController).isConnected();

        CastDevice castDevice = mock(CastDevice.class);
        doReturn("device-id").when(castDevice).getDeviceId();
        doReturn("CastDevice friendly name").when(castDevice).getFriendlyName();
        doReturn(castDevice).when(mSession).getCastDevice();
        ApplicationMetadata appMetadata = mock(ApplicationMetadata.class);
        doReturn("app-id").when(appMetadata).getApplicationId();
        doReturn(appMetadata).when(mSession).getApplicationMetadata();
        doReturn(1.0).when(mSession).getVolume();
        doReturn(false).when(mSession).isMute();
        doReturn("status text").when(mSession).getApplicationStatus();
        doReturn(1).when(mSession).getActiveInputState();
        doReturn(Arrays.asList("namespace-1", "namespace-2"))
                .when(mSessionController)
                .getNamespaces();
        doReturn(Arrays.asList("audio_in", "audio_out", "video_in", "video_out"))
                .when(mSessionController)
                .getCapabilities();

        assertEquals(mMessageHandler.buildSessionMessage(), "{}");
    }

    private JSONObject buildCastV2Message(String clientId, JSONObject innerMessage)
            throws JSONException {
        JSONObject message = new JSONObject();
        message.put("type", "v2_message");
        message.put("message", innerMessage);
        message.put("sequenceNumber", SEQUENCE_NUMBER1);
        message.put("timeoutMillis", 0);
        message.put("clientId", clientId);

        return message;
    }

    private JSONObject buildAppMessage(String clientId, String namespace, Object actualMessage)
            throws JSONException {
        JSONObject innerMessage = new JSONObject();
        innerMessage.put("sessionId", mSessionController.getSessionId());
        innerMessage.put("namespaceName", namespace);
        innerMessage.put("message", actualMessage);

        JSONObject message = new JSONObject();
        message.put("type", "app_message");
        message.put("message", innerMessage);
        message.put("sequenceNumber", SEQUENCE_NUMBER1);
        message.put("timeoutMillis", 0);
        message.put("clientId", clientId);

        return message;
    }

    private JSONObject buildActualAppMessage() throws JSONException {
        JSONObject message = new JSONObject();
        message.put("type", "actual app message type");

        return message;
    }

    private JSONObject buildSessionMessage(String sessionId) throws JSONException {
        JSONObject message = new JSONObject();
        message.put("sessionId", sessionId);

        return message;
    }

    private void expectException(CheckedRunnable r, Class exceptionClass) {
        boolean caughtException = false;
        try {
            r.run();
        } catch (Exception e) {
            if (e.getClass() == exceptionClass) caughtException = true;
        }
        assertTrue(caughtException);
    }

    private JSONObject buildJsonCastMessage(String message) throws JSONException {
        JSONObject jsonMessage = new JSONObject();
        jsonMessage.put("requestId", REQUEST_ID1);
        jsonMessage.put("message", message);
        return jsonMessage;
    }

    private void verifySimpleSessionMessage(JSONObject message, String type, int sequenceNumber,
            String clientId) throws JSONException {
        assertEquals(message.getString("type"), type);
        assertEquals(message.getInt("sequenceNumber"), sequenceNumber);
        assertEquals(message.getInt("timeoutMillis"), 0);
        assertEquals(message.getInt("sequenceNumber"), sequenceNumber);
    }

    private void prepareClientRecord(String routeId, String clientId, String appId,
            String autoJoinPolicy, String origin, int tabId) {
        ClientRecord clientRecord =
                new ClientRecord(routeId, clientId, appId, autoJoinPolicy, origin, tabId);
        mClientRecordMap.put(clientId, clientRecord);
    }

    private JSONObject buildLeaveSessionMessage(
            String clientId, String sessionId, int sequenceNumber) throws JSONException {
        JSONObject message = new JSONObject();
        message.put("type", "leave_session");
        message.put("clientId", clientId);
        message.put("message", sessionId);
        message.put("sequenceNumber", sequenceNumber);
        return message;
    }
}
