/*
 *  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.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.RobolectricTestRunner;
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(RobolectricTestRunner.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. Chosen quite arbitrarily and
   * could be made smaller if need be.
   */
  private static final int SERVER_WAIT = 10;
  private static final int CONNECT_TIMEOUT = 100;
  private static final int SEND_TIMEOUT = 100;
  private static final int DISCONNECT_TIMEOUT = 100;
  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());
    }
  }
}
