/*
 *  Copyright (c) 2012 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 <vector>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/test/channel_transport/udp_transport.h"
// We include the implementation header file to get at the dependency-injecting
// constructor.
#include "webrtc/test/channel_transport/udp_transport_impl.h"
// We must mock the socket manager, for which we need its definition.
#include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h"

using ::testing::_;
using ::testing::Return;

namespace webrtc {
namespace test {

class MockUdpSocketWrapper : public UdpSocketWrapper {
 public:
  // The following methods have to be mocked because they are pure.
  MOCK_METHOD1(ChangeUniqueId, int32_t(int32_t));
  MOCK_METHOD2(SetCallback, bool(CallbackObj, IncomingSocketCallback));
  MOCK_METHOD1(Bind, bool(const SocketAddress&));
  MOCK_METHOD0(ValidHandle, bool());
  MOCK_METHOD4(SetSockopt, bool(int32_t, int32_t,
                                const int8_t*,
                                int32_t));
  MOCK_METHOD1(SetTOS, int32_t(int32_t));
  MOCK_METHOD3(SendTo, int32_t(const int8_t*, size_t, const SocketAddress&));
  MOCK_METHOD8(SetQos, bool(int32_t, int32_t,
                            int32_t, int32_t,
                            int32_t, int32_t,
                            const SocketAddress &,
                            int32_t));
};

class MockUdpSocketManager : public UdpSocketManager {
 public:
  // Access to protected destructor.
  void Destroy() {
    delete this;
  }
  MOCK_METHOD2(Init, bool(int32_t, uint8_t&));
  MOCK_METHOD1(ChangeUniqueId, int32_t(const int32_t));
  MOCK_METHOD0(Start, bool());
  MOCK_METHOD0(Stop, bool());
  MOCK_METHOD1(AddSocket, bool(UdpSocketWrapper*));
  MOCK_METHOD1(RemoveSocket, bool(UdpSocketWrapper*));
};

class MockSocketFactory :
    public UdpTransportImpl::SocketFactoryInterface {
 public:
  MockSocketFactory(std::vector<MockUdpSocketWrapper*>* socket_counter)
      : socket_counter_(socket_counter) {
  }
  UdpSocketWrapper* CreateSocket(const int32_t id,
                                 UdpSocketManager* mgr,
                                 CallbackObj obj,
                                 IncomingSocketCallback cb,
                                 bool ipV6Enable,
                                 bool disableGQOS) {
    MockUdpSocketWrapper* socket = new MockUdpSocketWrapper();
    // We instrument the socket with calls that are expected, but do
    // not matter for any specific test, in order to avoid warning messages.
    EXPECT_CALL(*socket, ValidHandle()).WillRepeatedly(Return(true));
    EXPECT_CALL(*socket, Bind(_)).WillOnce(Return(true));
    socket_counter_->push_back(socket);
    return socket;
  }
  std::vector<MockUdpSocketWrapper*>* socket_counter_;
};

class UDPTransportTest : public ::testing::Test {
 public:
  UDPTransportTest()
      : sockets_created_(0) {
  }

  ~UDPTransportTest() {
    // In production, sockets register themselves at creation time with
    // an UdpSocketManager, and the UdpSocketManager is responsible for
    // deleting them. In this test, we just delete them after the test.
    while (!sockets_created_.empty()) {
      delete sockets_created_.back();
      sockets_created_.pop_back();
    }
  }

  int NumSocketsCreated() {
    return sockets_created_.size();
  }

  std::vector<MockUdpSocketWrapper*>* sockets_created() {
    return &sockets_created_;
  }
private:
  std::vector<MockUdpSocketWrapper*> sockets_created_;
};

TEST_F(UDPTransportTest, CreateTransport) {
  int32_t id = 0;
  uint8_t threads = 1;
  UdpTransport* transport = UdpTransport::Create(id, threads);
  UdpTransport::Destroy(transport);
}

// This test verifies that the mock_socket is not called from the constructor.
TEST_F(UDPTransportTest, ConstructorDoesNotCreateSocket) {
  int32_t id = 0;
  UdpTransportImpl::SocketFactoryInterface* null_maker = NULL;
  UdpSocketManager* null_manager = NULL;
  UdpTransport* transport = new UdpTransportImpl(id,
                                                 null_maker,
                                                 null_manager);
  delete transport;
}

TEST_F(UDPTransportTest, InitializeSourcePorts) {
  int32_t id = 0;
  UdpTransportImpl::SocketFactoryInterface* mock_maker
      = new MockSocketFactory(sockets_created());
  MockUdpSocketManager* mock_manager = new MockUdpSocketManager();
  UdpTransport* transport = new UdpTransportImpl(id,
                                                 mock_maker,
                                                 mock_manager);
  EXPECT_EQ(0, transport->InitializeSourcePorts(4711, 4712));
  EXPECT_EQ(2, NumSocketsCreated());

  delete transport;
  mock_manager->Destroy();
}

}  // namespace test
}  // namespace webrtc
