/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.appspot.apprtc;

import static org.junit.Assert.fail;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import org.chromium.base.test.util.DisabledTest;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLog;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class TCPChannelClientTest {
  private static final int PORT = 8888;
  /**
   * How long we wait before trying to connect to the server. Note: was
   * previously only 10, which was too short (tests were flaky).
   */
  private static final int SERVER_WAIT = 300;
  private static final int CONNECT_TIMEOUT = 1000;
  private static final int SEND_TIMEOUT = 1000;
  private static final int DISCONNECT_TIMEOUT = 1000;
  private static final int TERMINATION_TIMEOUT = 1000;
  private static final String TEST_MESSAGE_SERVER = "Hello, Server!";
  private static final String TEST_MESSAGE_CLIENT = "Hello, Client!";

  @Mock TCPChannelClient.TCPChannelEvents serverEvents;
  @Mock TCPChannelClient.TCPChannelEvents clientEvents;

  private ExecutorService executor;
  private TCPChannelClient server;
  private TCPChannelClient client;

  @Before
  public void setUp() {
    ShadowLog.stream = System.out;

    MockitoAnnotations.initMocks(this);

    executor = Executors.newSingleThreadExecutor();
  }

  @After
  public void tearDown() {
    verifyNoMoreEvents();

    executeAndWait(new Runnable() {
      @Override
      public void run() {
        client.disconnect();
        server.disconnect();
      }
    });

    // Stop the executor thread
    executor.shutdown();
    try {
      executor.awaitTermination(TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
  }

  @Test
  public void testConnectIPv4() {
    setUpIPv4Server();
    try {
      Thread.sleep(SERVER_WAIT);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
    setUpIPv4Client();

    verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true);
    verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false);
  }

  @Test
  public void testConnectIPv6() {
    setUpIPv6Server();
    try {
      Thread.sleep(SERVER_WAIT);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
    setUpIPv6Client();

    verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true);
    verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false);
  }

  @Test
  public void testSendData() {
    testConnectIPv4();

    executeAndWait(new Runnable() {
      @Override
      public void run() {
        client.send(TEST_MESSAGE_SERVER);
        server.send(TEST_MESSAGE_CLIENT);
      }
    });

    verify(serverEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_SERVER);
    verify(clientEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_CLIENT);
  }

  @Test
  public void testDisconnectServer() {
    testConnectIPv4();
    executeAndWait(new Runnable() {
      @Override
      public void run() {
        server.disconnect();
      }
    });

    verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
    verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
  }

  @Test
  public void testDisconnectClient() {
    testConnectIPv4();
    executeAndWait(new Runnable() {
      @Override
      public void run() {
        client.disconnect();
      }
    });

    verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
    verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
  }

  private void setUpIPv4Server() {
    setUpServer("0.0.0.0", PORT);
  }

  private void setUpIPv4Client() {
    setUpClient("127.0.0.1", PORT);
  }

  private void setUpIPv6Server() {
    setUpServer("::", PORT);
  }

  private void setUpIPv6Client() {
    setUpClient("::1", PORT);
  }

  private void setUpServer(String ip, int port) {
    server = new TCPChannelClient(executor, serverEvents, ip, port);
  }

  private void setUpClient(String ip, int port) {
    client = new TCPChannelClient(executor, clientEvents, ip, port);
  }

  /**
   * Verifies no more server or client events have been issued
   */
  private void verifyNoMoreEvents() {
    verifyNoMoreInteractions(serverEvents);
    verifyNoMoreInteractions(clientEvents);
  }

  /**
   * Queues runnable to be run and waits for it to be executed by the executor thread
   */
  public void executeAndWait(Runnable runnable) {
    try {
      executor.submit(runnable).get();
    } catch (Exception e) {
      fail(e.getMessage());
    }
  }
}
