/*
 *  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.Ignore;
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 org.robolectric.RobolectricTestRunner;

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. 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());
    }
  }

  private void connectIPv4Helper() {
    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 testConnectIPv4() {
    connectIPv4Helper();
  }

  // TODO:b/389829614 - Below test is failing.
  @Test
  @Ignore
  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() {
    connectIPv4Helper();

    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() {
    connectIPv4Helper();
    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() {
    connectIPv4Helper();
    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());
    }
  }
}
