/*
 *  Copyright 2009 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.
 */

#include <memory>

#include "webrtc/p2p/base/basicpacketsocketfactory.h"
#include "webrtc/p2p/base/relayport.h"
#include "webrtc/p2p/base/relayserver.h"
#include "webrtc/rtc_base/gunit.h"
#include "webrtc/rtc_base/helpers.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/socketadapters.h"
#include "webrtc/rtc_base/socketaddress.h"
#include "webrtc/rtc_base/ssladapter.h"
#include "webrtc/rtc_base/thread.h"
#include "webrtc/rtc_base/virtualsocketserver.h"

using rtc::SocketAddress;

static const SocketAddress kLocalAddress = SocketAddress("192.168.1.2", 0);
static const SocketAddress kRelayUdpAddr = SocketAddress("99.99.99.1", 5000);
static const SocketAddress kRelayTcpAddr = SocketAddress("99.99.99.2", 5001);
static const SocketAddress kRelaySslAddr = SocketAddress("99.99.99.3", 443);
static const SocketAddress kRelayExtAddr = SocketAddress("99.99.99.3", 5002);

static const int kTimeoutMs = 1000;
static const int kMaxTimeoutMs = 5000;

// Tests connecting a RelayPort to a fake relay server
// (cricket::RelayServer) using all currently available protocols. The
// network layer is faked out by using a VirtualSocketServer for
// creating sockets. The test will monitor the current state of the
// RelayPort and created sockets by listening for signals such as,
// SignalConnectFailure, SignalConnectTimeout, SignalSocketClosed and
// SignalReadPacket.
class RelayPortTest : public testing::Test,
                      public sigslot::has_slots<> {
 public:
  RelayPortTest()
      : virtual_socket_server_(new rtc::VirtualSocketServer()),
        main_(virtual_socket_server_.get()),
        network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
        socket_factory_(rtc::Thread::Current()),
        username_(rtc::CreateRandomString(16)),
        password_(rtc::CreateRandomString(16)),
        relay_port_(cricket::RelayPort::Create(&main_,
                                               &socket_factory_,
                                               &network_,
                                               kLocalAddress.ipaddr(),
                                               0,
                                               0,
                                               username_,
                                               password_)),
        relay_server_(new cricket::RelayServer(&main_)) {}

  void OnReadPacket(rtc::AsyncPacketSocket* socket,
                    const char* data, size_t size,
                    const rtc::SocketAddress& remote_addr,
                    const rtc::PacketTime& packet_time) {
    received_packet_count_[socket]++;
  }

  void OnConnectFailure(const cricket::ProtocolAddress* addr) {
    failed_connections_.push_back(*addr);
  }

  void OnSoftTimeout(const cricket::ProtocolAddress* addr) {
    soft_timedout_connections_.push_back(*addr);
  }

 protected:
  virtual void SetUp() {
    // The relay server needs an external socket to work properly.
    rtc::AsyncUDPSocket* ext_socket =
        CreateAsyncUdpSocket(kRelayExtAddr);
    relay_server_->AddExternalSocket(ext_socket);

    // Listen for failures.
    relay_port_->SignalConnectFailure.
        connect(this, &RelayPortTest::OnConnectFailure);

    // Listen for soft timeouts.
    relay_port_->SignalSoftTimeout.
        connect(this, &RelayPortTest::OnSoftTimeout);
  }

  // Udp has the highest 'goodness' value of the three different
  // protocols used for connecting to the relay server. As soon as
  // PrepareAddress is called, the RelayPort will start trying to
  // connect to the given UDP address. As soon as a response to the
  // sent STUN allocate request message has been received, the
  // RelayPort will consider the connection to be complete and will
  // abort any other connection attempts.
  void TestConnectUdp() {
    // Add a UDP socket to the relay server.
    rtc::AsyncUDPSocket* internal_udp_socket =
        CreateAsyncUdpSocket(kRelayUdpAddr);
    rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);

    relay_server_->AddInternalSocket(internal_udp_socket);
    relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);

    // Now add our relay addresses to the relay port and let it start.
    relay_port_->AddServerAddress(
        cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP));
    relay_port_->AddServerAddress(
        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
    relay_port_->PrepareAddress();

    // Should be connected.
    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kTimeoutMs);

    // Make sure that we are happy with UDP, ie. not continuing with
    // TCP, SSLTCP, etc.
    WAIT(relay_server_->HasConnection(kRelayTcpAddr), kTimeoutMs);

    // Should have only one connection.
    EXPECT_EQ(1, relay_server_->GetConnectionCount());

    // Should be the UDP address.
    EXPECT_TRUE(relay_server_->HasConnection(kRelayUdpAddr));
  }

  // TCP has the second best 'goodness' value, and as soon as UDP
  // connection has failed, the RelayPort will attempt to connect via
  // TCP. Here we add a fake UDP address together with a real TCP
  // address to simulate an UDP failure. As soon as UDP has failed the
  // RelayPort will try the TCP adress and succed.
  void TestConnectTcp() {
    // Create a fake UDP address for relay port to simulate a failure.
    cricket::ProtocolAddress fake_protocol_address =
        cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP);

    // Create a server socket for the RelayServer.
    rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
    relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);

    // Add server addresses to the relay port and let it start.
    relay_port_->AddServerAddress(
        cricket::ProtocolAddress(fake_protocol_address));
    relay_port_->AddServerAddress(
        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
    relay_port_->PrepareAddress();

    EXPECT_FALSE(relay_port_->IsReady());

    // Should have timed out in 200 + 200 + 400 + 800 + 1600 ms = 3200ms.
    // Add some margin of error for slow bots.
    // TODO(deadbeef): Use simulated clock instead of just increasing timeouts
    // to fix flaky tests.
    EXPECT_TRUE_WAIT(HasFailed(&fake_protocol_address), 5000);

    // Wait until relayport is ready.
    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);

    // Should have only one connection.
    EXPECT_EQ(1, relay_server_->GetConnectionCount());

    // Should be the TCP address.
    EXPECT_TRUE(relay_server_->HasConnection(kRelayTcpAddr));
  }

  void TestConnectSslTcp() {
    // Create a fake TCP address for relay port to simulate a failure.
    // We skip UDP here since transition from UDP to TCP has been
    // tested above.
    cricket::ProtocolAddress fake_protocol_address =
        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP);

    // Create a ssl server socket for the RelayServer.
    rtc::AsyncSocket* ssl_server_socket =
        CreateServerSocket(kRelaySslAddr);
    relay_server_->AddInternalServerSocket(ssl_server_socket,
                                           cricket::PROTO_SSLTCP);

    // Create a tcp server socket that listens on the fake address so
    // the relay port can attempt to connect to it.
    std::unique_ptr<rtc::AsyncSocket> tcp_server_socket(
        CreateServerSocket(kRelayTcpAddr));

    // Add server addresses to the relay port and let it start.
    relay_port_->AddServerAddress(fake_protocol_address);
    relay_port_->AddServerAddress(
        cricket::ProtocolAddress(kRelaySslAddr, cricket::PROTO_SSLTCP));
    relay_port_->PrepareAddress();
    EXPECT_FALSE(relay_port_->IsReady());

    // Should have timed out in 3000 ms(relayport.cc, kSoftConnectTimeoutMs).
    EXPECT_TRUE_WAIT_MARGIN(HasTimedOut(&fake_protocol_address), 3000, 100);

    // Wait until relayport is ready.
    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);

    // Should have only one connection.
    EXPECT_EQ(1, relay_server_->GetConnectionCount());

    // Should be the SSLTCP address.
    EXPECT_TRUE(relay_server_->HasConnection(kRelaySslAddr));
  }

 private:
  rtc::AsyncUDPSocket* CreateAsyncUdpSocket(const SocketAddress addr) {
    rtc::AsyncSocket* socket =
        virtual_socket_server_->CreateAsyncSocket(SOCK_DGRAM);
    rtc::AsyncUDPSocket* packet_socket =
        rtc::AsyncUDPSocket::Create(socket, addr);
    EXPECT_TRUE(packet_socket != NULL);
    packet_socket->SignalReadPacket.connect(this, &RelayPortTest::OnReadPacket);
    return packet_socket;
  }

  rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
    rtc::AsyncSocket* socket =
        virtual_socket_server_->CreateAsyncSocket(SOCK_STREAM);
    EXPECT_GE(socket->Bind(addr), 0);
    EXPECT_GE(socket->Listen(5), 0);
    return socket;
  }

  bool HasFailed(cricket::ProtocolAddress* addr) {
    for (size_t i = 0; i < failed_connections_.size(); i++) {
      if (failed_connections_[i].address == addr->address &&
          failed_connections_[i].proto == addr->proto) {
        return true;
      }
    }
    return false;
  }

  bool HasTimedOut(cricket::ProtocolAddress* addr) {
    for (size_t i = 0; i < soft_timedout_connections_.size(); i++) {
      if (soft_timedout_connections_[i].address == addr->address &&
          soft_timedout_connections_[i].proto == addr->proto) {
        return true;
      }
    }
    return false;
  }

  typedef std::map<rtc::AsyncPacketSocket*, int> PacketMap;

  std::unique_ptr<rtc::VirtualSocketServer> virtual_socket_server_;
  rtc::AutoSocketServerThread main_;
  rtc::Network network_;
  rtc::BasicPacketSocketFactory socket_factory_;
  std::string username_;
  std::string password_;
  std::unique_ptr<cricket::RelayPort> relay_port_;
  std::unique_ptr<cricket::RelayServer> relay_server_;
  std::vector<cricket::ProtocolAddress> failed_connections_;
  std::vector<cricket::ProtocolAddress> soft_timedout_connections_;
  PacketMap received_packet_count_;
};

TEST_F(RelayPortTest, ConnectUdp) {
  TestConnectUdp();
}

TEST_F(RelayPortTest, ConnectTcp) {
  TestConnectTcp();
}

TEST_F(RelayPortTest, ConnectSslTcp) {
  TestConnectSslTcp();
}
