/*
 * libjingle
 * Copyright 2009 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/base/fakenetwork.h"
#include "talk/base/firewallsocketserver.h"
#include "talk/base/gunit.h"
#include "talk/base/helpers.h"
#include "talk/base/logging.h"
#include "talk/base/network.h"
#include "talk/base/physicalsocketserver.h"
#include "talk/base/socketaddress.h"
#include "talk/base/thread.h"
#include "talk/base/virtualsocketserver.h"
#include "talk/p2p/base/testrelayserver.h"
#include "talk/p2p/base/teststunserver.h"
#include "talk/p2p/client/basicportallocator.h"
#include "talk/p2p/client/httpportallocator.h"

using talk_base::SocketAddress;
using talk_base::Thread;

static const SocketAddress kClientAddr("11.11.11.11", 0);
static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);

// Minimum and maximum port for port range tests.
static const int kMinPort = 10000;
static const int kMaxPort = 10099;

// Helper for dumping candidates
std::ostream& operator<<(std::ostream& os, const cricket::Candidate& c) {
  os << c.ToString();
  return os;
}

class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
 public:
  static void SetUpTestCase() {
    // Ensure the RNG is inited.
    talk_base::InitRandom(NULL, 0);
  }
  PortAllocatorTest()
      : pss_(new talk_base::PhysicalSocketServer),
        vss_(new talk_base::VirtualSocketServer(pss_.get())),
        fss_(new talk_base::FirewallSocketServer(vss_.get())),
        ss_scope_(fss_.get()),
        stun_server_(Thread::Current(), kStunAddr),
        relay_server_(Thread::Current(), kRelayUdpIntAddr, kRelayUdpExtAddr,
                      kRelayTcpIntAddr, kRelayTcpExtAddr,
                      kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
        allocator_(&network_manager_, kStunAddr,
                   kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr) {
  }

  void AddInterface(const SocketAddress& addr) {
    network_manager_.AddInterface(addr);
  }
  bool SetPortRange(int min_port, int max_port) {
    return allocator_.SetPortRange(min_port, max_port);
  }
  bool CreateSession(const std::string& name, const std::string& type) {
    session_.reset(allocator_.CreateSession(name, type));
    if (!session_.get())
      return false;

    session_->SignalPortReady.connect(this,
        &PortAllocatorTest::OnPortReady);
    session_->SignalCandidatesReady.connect(this,
        &PortAllocatorTest::OnCandidatesReady);
    return true;
  }

  static bool CheckCandidate(const cricket::Candidate& c,
                             const std::string& name, const std::string& type,
                             const std::string& proto,
                             const SocketAddress& addr) {
    return (c.name() == name && c.type() == type &&
        c.protocol() == proto && c.address().ip() == addr.ip() &&
        (addr.port() == 0 || (c.address().port() == addr.port())));
  }
  static bool CheckPort(const talk_base::SocketAddress& addr,
                        int min_port, int max_port) {
    return (addr.port() >= min_port && addr.port() <= max_port);
  }

 protected:
  cricket::BasicPortAllocator& allocator() { return allocator_; }

  void OnPortReady(cricket::PortAllocatorSession* ses, cricket::Port* port) {
    LOG(LS_INFO) << "OnPortReady: " << port->ToString();
    ports_.push_back(port);
  }
  void OnCandidatesReady(cricket::PortAllocatorSession* ses,
                         const std::vector<cricket::Candidate>& candidates) {
    for (size_t i = 0; i < candidates.size(); ++i) {
      LOG(LS_INFO) << "OnCandidatesReady: " << candidates[i].ToString();
      candidates_.push_back(candidates[i]);
    }
  }

  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
  talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
  talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
  talk_base::SocketServerScope ss_scope_;
  cricket::TestStunServer stun_server_;
  cricket::TestRelayServer relay_server_;
  talk_base::FakeNetworkManager network_manager_;
  cricket::BasicPortAllocator allocator_;
  talk_base::scoped_ptr<cricket::PortAllocatorSession> session_;
  std::vector<cricket::Port*> ports_;
  std::vector<cricket::Candidate> candidates_;
};

// Tests that we can init the port allocator and create a session.
TEST_F(PortAllocatorTest, TestBasic) {
  EXPECT_EQ(&network_manager_, allocator().network_manager());
  EXPECT_EQ(kStunAddr, allocator().stun_address());
  EXPECT_EQ(kRelayUdpIntAddr, allocator().relay_address_udp());
  EXPECT_EQ(kRelayTcpIntAddr, allocator().relay_address_tcp());
  EXPECT_EQ(kRelaySslTcpIntAddr, allocator().relay_address_ssl());
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
}

// Tests that we can get the local and STUN addresses successfully.
TEST_F(PortAllocatorTest, TestGetInitialPorts) {
  AddInterface(kClientAddr);
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
  EXPECT_PRED5(CheckCandidate, candidates_[0],
      "rtp", "local", "udp", kClientAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[1],
      "rtp", "stun", "udp", kClientAddr);
  EXPECT_EQ(2U, ports_.size());
}

// Tests that we can get all the desired addresses successfully.
TEST_F(PortAllocatorTest, TestGetAllPorts) {
  AddInterface(kClientAddr);
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  session_->StartGetAllPorts();
  ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
  EXPECT_EQ(2U, ports_.size());
  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
  EXPECT_EQ(3U, ports_.size());
  EXPECT_PRED5(CheckCandidate, candidates_[2],
      "rtp", "relay", "udp", kRelayUdpIntAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[3],
      "rtp", "relay", "udp", kRelayUdpExtAddr);
  ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
  EXPECT_PRED5(CheckCandidate, candidates_[4],
      "rtp", "relay", "tcp", kRelayTcpIntAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[5],
      "rtp", "local", "tcp", kClientAddr);
  EXPECT_EQ(4U, ports_.size());
  ASSERT_EQ_WAIT(7U, candidates_.size(), 2000);
  EXPECT_PRED5(CheckCandidate, candidates_[6],
      "rtp", "relay", "ssltcp", kRelaySslTcpIntAddr);
  EXPECT_EQ(4U, ports_.size());
}

// Test that we restrict client ports appropriately when a port range is set.
// We check the candidates for udp/stun/tcp ports, and the from address
// for relay ports.
TEST_F(PortAllocatorTest, TestGetAllPortsPortRange) {
  AddInterface(kClientAddr);
  // Check that an invalid port range fails.
  EXPECT_FALSE(SetPortRange(kMaxPort, kMinPort));
  // Check that a null port range succeeds.
  EXPECT_TRUE(SetPortRange(0, 0));
  // Check that a valid port range succeeds.
  EXPECT_TRUE(SetPortRange(kMinPort, kMaxPort));
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  session_->StartGetAllPorts();
  ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
  EXPECT_EQ(2U, ports_.size());
  // Check the port number for the UDP port object.
  EXPECT_PRED3(CheckPort, candidates_[0].address(), kMinPort, kMaxPort);
  // Check the port number for the STUN port object.
  EXPECT_PRED3(CheckPort, candidates_[1].address(), kMinPort, kMaxPort);
  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
  EXPECT_EQ(3U, ports_.size());
  // Check the port number used to connect to the relay server.
  EXPECT_PRED3(CheckPort, relay_server_.GetConnection(0).source(),
               kMinPort, kMaxPort);
  ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
  EXPECT_EQ(4U, ports_.size());
  // Check the port number for the TCP port object.
  EXPECT_PRED3(CheckPort, candidates_[5].address(), kMinPort, kMaxPort);
}

// Test that we don't crash or malfunction if we have no network adapters.
// TODO: Find a way to exit early here.
TEST_F(PortAllocatorTest, TestGetAllPortsNoAdapters) {
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  session_->StartGetAllPorts();
  WAIT(candidates_.size() > 0, 2000);
}

// Test that we don't crash or malfunction if we can't create UDP sockets.
TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSockets) {
  AddInterface(kClientAddr);
  fss_->set_udp_sockets_enabled(false);
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  session_->StartGetAllPorts();
  ASSERT_EQ_WAIT(2U, candidates_.size(), 2000);
  EXPECT_PRED5(CheckCandidate, candidates_[0],
      "rtp", "relay", "udp", kRelayUdpIntAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[1],
      "rtp", "relay", "udp", kRelayUdpExtAddr);
  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
  EXPECT_PRED5(CheckCandidate, candidates_[2],
      "rtp", "relay", "tcp", kRelayTcpIntAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[3],
      "rtp", "local", "tcp", kClientAddr);
  EXPECT_EQ(2U, ports_.size());
  ASSERT_EQ_WAIT(5U, candidates_.size(), 2000);
  EXPECT_PRED5(CheckCandidate, candidates_[4],
      "rtp", "relay", "ssltcp", kRelaySslTcpIntAddr);
  EXPECT_EQ(2U, ports_.size());
}

// Test that we don't crash or malfunction if we can't create UDP sockets or
// listen on TCP sockets. We still give out a local TCP address, since
// apparently this is needed for the remote side to accept our connection.
TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSocketsNoTcpListen) {
  AddInterface(kClientAddr);
  fss_->set_udp_sockets_enabled(false);
  fss_->set_tcp_listen_enabled(false);
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  session_->StartGetAllPorts();
  ASSERT_EQ_WAIT(2U, candidates_.size(), 3000);
  EXPECT_PRED5(CheckCandidate, candidates_[0],
      "rtp", "relay", "udp", kRelayUdpIntAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[1],
      "rtp", "relay", "udp", kRelayUdpExtAddr);
  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
  EXPECT_PRED5(CheckCandidate, candidates_[2],
      "rtp", "relay", "tcp", kRelayTcpIntAddr);
  EXPECT_PRED5(CheckCandidate, candidates_[3],
      "rtp", "local", "tcp", kClientAddr);
  EXPECT_EQ(2U, ports_.size());
  ASSERT_EQ_WAIT(5U, candidates_.size(), 2000);
  EXPECT_PRED5(CheckCandidate, candidates_[4],
      "rtp", "relay", "ssltcp", kRelaySslTcpIntAddr);
  EXPECT_EQ(2U, ports_.size());
}

// Test that we don't crash or malfunction if we can't create any sockets.
// TODO: Find a way to exit early here.
TEST_F(PortAllocatorTest, TestGetAllPortsNoSockets) {
  AddInterface(kClientAddr);
  fss_->set_tcp_sockets_enabled(false);
  fss_->set_udp_sockets_enabled(false);
  EXPECT_TRUE(CreateSession("rtp", "unittest"));
  session_->GetInitialPorts();
  session_->StartGetAllPorts();
  WAIT(candidates_.size() > 0, 2000);
}

// Test that the httpportallocator correctly maintains its lists of stun and
// relay servers, by never allowing an empty list.
TEST(HttpPortAllocatorTest, TestHttpPortAllocatorHostLists) {
  talk_base::FakeNetworkManager network_manager;
  cricket::HttpPortAllocator alloc(&network_manager, "unit test agent");
  EXPECT_EQ(1U, alloc.relay_hosts().size());
  EXPECT_EQ(1U, alloc.stun_hosts().size());

  std::vector<std::string> relay_servers;
  std::vector<talk_base::SocketAddress> stun_servers;

  alloc.SetRelayHosts(relay_servers);
  alloc.SetStunHosts(stun_servers);
  EXPECT_EQ(1U, alloc.relay_hosts().size());
  EXPECT_EQ(1U, alloc.stun_hosts().size());

  relay_servers.push_back("1.unittest.corp.google.com");
  relay_servers.push_back("2.unittest.corp.google.com");
  stun_servers.push_back(
      talk_base::SocketAddress("1.unittest.corp.google.com", 0));
  stun_servers.push_back(
      talk_base::SocketAddress("2.unittest.corp.google.com", 0));
  alloc.SetRelayHosts(relay_servers);
  alloc.SetStunHosts(stun_servers);
  EXPECT_EQ(2U, alloc.relay_hosts().size());
  EXPECT_EQ(2U, alloc.stun_hosts().size());
}
