/*
 *  Copyright 2015 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 "webrtc/base/asyncresolverinterface.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/bind.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/physicalsocketserver.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/ssladapter.h"
#include "webrtc/base/virtualsocketserver.h"
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
#include "webrtc/p2p/base/teststunserver.h"
#include "webrtc/p2p/stunprober/stunprober.h"

using stunprober::StunProber;
using stunprober::AsyncCallback;

namespace stunprober {

namespace {

const rtc::SocketAddress kLocalAddr("192.168.0.1", 0);
const rtc::SocketAddress kStunAddr1("1.1.1.1", 3478);
const rtc::SocketAddress kStunAddr2("1.1.1.2", 3478);
const rtc::SocketAddress kFailedStunAddr("1.1.1.3", 3478);
const rtc::SocketAddress kStunMappedAddr("77.77.77.77", 0);

}  // namespace

class StunProberTest : public testing::Test {
 public:
  StunProberTest()
      : main_(rtc::Thread::Current()),
        pss_(new rtc::PhysicalSocketServer),
        ss_(new rtc::VirtualSocketServer(pss_.get())),
        ss_scope_(ss_.get()),
        result_(StunProber::SUCCESS),
        stun_server_1_(cricket::TestStunServer::Create(rtc::Thread::Current(),
                                                       kStunAddr1)),
        stun_server_2_(cricket::TestStunServer::Create(rtc::Thread::Current(),
                                                       kStunAddr2)) {
    stun_server_1_->set_fake_stun_addr(kStunMappedAddr);
    stun_server_2_->set_fake_stun_addr(kStunMappedAddr);
    rtc::InitializeSSL();
  }

  void set_expected_result(int result) { result_ = result; }

  void StartProbing(rtc::PacketSocketFactory* socket_factory,
                    const std::vector<rtc::SocketAddress>& addrs,
                    const rtc::NetworkManager::NetworkList& networks,
                    bool shared_socket,
                    uint16 interval,
                    uint16 pings_per_ip) {
    prober.reset(
        new StunProber(socket_factory, rtc::Thread::Current(), networks));
    prober->Start(addrs, shared_socket, interval, pings_per_ip,
                  100 /* timeout_ms */, [this](StunProber* prober, int result) {
                    this->StopCallback(prober, result);
                  });
  }

  void RunProber(bool shared_mode) {
    const int pings_per_ip = 3;
    std::vector<rtc::SocketAddress> addrs;
    addrs.push_back(kStunAddr1);
    addrs.push_back(kStunAddr2);
    // Add a non-existing server. This shouldn't pollute the result.
    addrs.push_back(kFailedStunAddr);

    rtc::Network ipv4_network1("test_eth0", "Test Network Adapter 1",
                               rtc::IPAddress(0x12345600U), 24);
    ipv4_network1.AddIP(rtc::IPAddress(0x12345678));
    rtc::NetworkManager::NetworkList networks;
    networks.push_back(&ipv4_network1);

    rtc::scoped_ptr<rtc::BasicPacketSocketFactory> socket_factory(
        new rtc::BasicPacketSocketFactory());

    // Set up the expected results for verification.
    std::set<std::string> srflx_addresses;
    srflx_addresses.insert(kStunMappedAddr.ToString());
    const uint32 total_pings_tried =
        static_cast<uint32>(pings_per_ip * addrs.size());

    // The reported total_pings should not count for pings sent to the
    // kFailedStunAddr.
    const uint32 total_pings_reported = total_pings_tried - pings_per_ip;

    StartProbing(socket_factory.get(), addrs, networks, shared_mode, 3,
                 pings_per_ip);

    WAIT(stopped_, 1000);

    StunProber::Stats stats;
    EXPECT_TRUE(prober->GetStats(&stats));
    EXPECT_EQ(stats.success_percent, 100);
    EXPECT_TRUE(stats.nat_type > stunprober::NATTYPE_NONE);
    EXPECT_EQ(stats.srflx_addrs, srflx_addresses);
    EXPECT_EQ(static_cast<uint32>(stats.num_request_sent),
              total_pings_reported);
    EXPECT_EQ(static_cast<uint32>(stats.num_response_received),
              total_pings_reported);
  }

 private:
  void StopCallback(StunProber* prober, int result) {
    EXPECT_EQ(result, result_);
    stopped_ = true;
  }

  rtc::Thread* main_;
  rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
  rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
  rtc::SocketServerScope ss_scope_;
  rtc::scoped_ptr<StunProber> prober;
  int result_ = 0;
  bool stopped_ = false;
  rtc::scoped_ptr<cricket::TestStunServer> stun_server_1_;
  rtc::scoped_ptr<cricket::TestStunServer> stun_server_2_;
};

TEST_F(StunProberTest, NonSharedMode) {
  RunProber(false);
}

TEST_F(StunProberTest, SharedMode) {
  RunProber(true);
}

}  // namespace stunprober
