// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/protocol/ice_transport.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "jingle/glue/thread_wrapper.h"
#include "net/url_request/url_request_context_getter.h"
#include "remoting/base/url_request.h"
#include "remoting/protocol/chromium_port_allocator_factory.h"
#include "remoting/protocol/connection_tester.h"
#include "remoting/protocol/fake_authenticator.h"
#include "remoting/protocol/message_channel_factory.h"
#include "remoting/protocol/message_pipe.h"
#include "remoting/protocol/transport_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"

using testing::_;

namespace remoting {
namespace protocol {

namespace {

// Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
// between messages (about 1 second for 100 messages).
const int kMessageSize = 1024;
const int kMessages = 100;
const char kChannelName[] = "test_channel";

ACTION_P2(QuitRunLoopOnCounter, run_loop, counter) {
  --(*counter);
  EXPECT_GE(*counter, 0);
  if (*counter == 0)
    run_loop->Quit();
}

class MockChannelCreatedCallback {
 public:
  MOCK_METHOD1(OnDone, void(MessagePipe* socket));
};

class TestTransportEventHandler : public IceTransport::EventHandler {
 public:
  typedef base::Callback<void(ErrorCode error)> ErrorCallback;

  TestTransportEventHandler() = default;
  ~TestTransportEventHandler() = default;

  void set_error_callback(const ErrorCallback& callback) {
    error_callback_ = callback;
  }

  // IceTransport::EventHandler interface.
  void OnIceTransportRouteChange(const std::string& channel_name,
                              const TransportRoute& route) override {}
  void OnIceTransportError(ErrorCode error) override {
    error_callback_.Run(error);
  }

 private:
  ErrorCallback error_callback_;

  DISALLOW_COPY_AND_ASSIGN(TestTransportEventHandler);
};

}  // namespace

class IceTransportTest : public testing::Test {
 public:
  IceTransportTest() {
    jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
    network_settings_ =
        NetworkSettings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
  }

  void TearDown() override {
    client_message_pipe_.reset();
    host_message_pipe_.reset();
    client_transport_.reset();
    host_transport_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void ProcessTransportInfo(std::unique_ptr<IceTransport>* target_transport,
                            std::unique_ptr<buzz::XmlElement> transport_info) {
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, base::Bind(&IceTransportTest::DeliverTransportInfo,
                              base::Unretained(this), target_transport,
                              base::Passed(&transport_info)),
        transport_info_delay_);
  }

  void DeliverTransportInfo(std::unique_ptr<IceTransport>* target_transport,
                            std::unique_ptr<buzz::XmlElement> transport_info) {
    ASSERT_TRUE(target_transport);
    EXPECT_TRUE(
        (*target_transport)->ProcessTransportInfo(transport_info.get()));
  }

  void InitializeConnection() {
    jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();

    host_transport_.reset(new IceTransport(
        new TransportContext(nullptr,
                             std::make_unique<ChromiumPortAllocatorFactory>(),
                             nullptr, network_settings_, TransportRole::SERVER),
        &host_event_handler_));
    if (!host_authenticator_) {
      host_authenticator_.reset(
          new FakeAuthenticator(FakeAuthenticator::ACCEPT));
    }

    client_transport_.reset(new IceTransport(
        new TransportContext(nullptr,
                             std::make_unique<ChromiumPortAllocatorFactory>(),
                             nullptr, network_settings_, TransportRole::CLIENT),
        &client_event_handler_));
    if (!client_authenticator_) {
      client_authenticator_.reset(
          new FakeAuthenticator(FakeAuthenticator::ACCEPT));
    }

    host_event_handler_.set_error_callback(base::Bind(
        &IceTransportTest::OnTransportError, base::Unretained(this)));
    client_event_handler_.set_error_callback(base::Bind(
        &IceTransportTest::OnTransportError, base::Unretained(this)));

    // Start both transports.
    host_transport_->Start(
        host_authenticator_.get(),
        base::Bind(&IceTransportTest::ProcessTransportInfo,
                   base::Unretained(this), &client_transport_));
    client_transport_->Start(
        client_authenticator_.get(),
        base::Bind(&IceTransportTest::ProcessTransportInfo,
                   base::Unretained(this), &host_transport_));
  }

  void WaitUntilConnected() {
    run_loop_.reset(new base::RunLoop());

    int counter = 2;
    EXPECT_CALL(client_channel_callback_, OnDone(_))
        .WillOnce(QuitRunLoopOnCounter(run_loop_.get(), &counter));
    EXPECT_CALL(host_channel_callback_, OnDone(_))
        .WillOnce(QuitRunLoopOnCounter(run_loop_.get(), &counter));

    run_loop_->Run();

    EXPECT_TRUE(client_message_pipe_.get());
    EXPECT_TRUE(host_message_pipe_.get());
  }

  void OnClientChannelCreated(std::unique_ptr<MessagePipe> message_pipe) {
    client_message_pipe_ = std::move(message_pipe);
    client_channel_callback_.OnDone(client_message_pipe_.get());
  }

  void OnHostChannelCreated(std::unique_ptr<MessagePipe> message_pipe) {
    host_message_pipe_ = std::move(message_pipe);
    host_channel_callback_.OnDone(host_message_pipe_.get());
  }

  void OnTransportError(ErrorCode error) {
    LOG(ERROR) << "Transport Error";
    error_ = error;
    run_loop_->Quit();
  }

 protected:
  base::MessageLoopForIO message_loop_;
  std::unique_ptr<base::RunLoop> run_loop_;

  NetworkSettings network_settings_;

  base::TimeDelta transport_info_delay_;

  std::unique_ptr<IceTransport> host_transport_;
  TestTransportEventHandler host_event_handler_;
  std::unique_ptr<FakeAuthenticator> host_authenticator_;

  std::unique_ptr<IceTransport> client_transport_;
  TestTransportEventHandler client_event_handler_;
  std::unique_ptr<FakeAuthenticator> client_authenticator_;

  MockChannelCreatedCallback client_channel_callback_;
  MockChannelCreatedCallback host_channel_callback_;

  std::unique_ptr<MessagePipe> client_message_pipe_;
  std::unique_ptr<MessagePipe> host_message_pipe_;

  ErrorCode error_ = OK;
};

TEST_F(IceTransportTest, DataStream) {
  InitializeConnection();

  client_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  host_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  WaitUntilConnected();

  MessagePipeConnectionTester tester(host_message_pipe_.get(),
                                     client_message_pipe_.get(), kMessageSize,
                                     kMessages);
  tester.RunAndCheckResults();
}

TEST_F(IceTransportTest, MuxDataStream) {
  InitializeConnection();

  client_transport_->GetMultiplexedChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  host_transport_->GetMultiplexedChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  WaitUntilConnected();

  MessagePipeConnectionTester tester(host_message_pipe_.get(),
                                     client_message_pipe_.get(), kMessageSize,
                                     kMessages);
  tester.RunAndCheckResults();
}

TEST_F(IceTransportTest, FailedChannelAuth) {
  // Use host authenticator with one that rejects channel authentication.
  host_authenticator_.reset(
      new FakeAuthenticator(FakeAuthenticator::REJECT_CHANNEL));

  InitializeConnection();

  client_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  host_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  run_loop_.reset(new base::RunLoop());

  // The callback should never be called.
  EXPECT_CALL(host_channel_callback_, OnDone(_)).Times(0);

  run_loop_->Run();

  EXPECT_FALSE(host_message_pipe_);
  EXPECT_EQ(CHANNEL_CONNECTION_ERROR, error_);

  client_transport_->GetChannelFactory()->CancelChannelCreation(
      kChannelName);
}

// Verify that channels are never marked connected if connection cannot be
// established.
TEST_F(IceTransportTest, TestBrokenTransport) {
  // Allow only incoming connections on both ends, which effectively renders
  // transport unusable. Also reduce connection timeout so the test finishes
  // quickly.
  network_settings_ = NetworkSettings(NetworkSettings::NAT_TRAVERSAL_DISABLED);
  network_settings_.ice_timeout = base::TimeDelta::FromSeconds(1);
  network_settings_.ice_reconnect_attempts = 1;

  InitializeConnection();

  client_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  host_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  // The RunLoop should quit in OnTransportError().
  run_loop_.reset(new base::RunLoop());
  run_loop_->Run();

  // Verify that neither of the two ends of the channel is connected.
  EXPECT_FALSE(client_message_pipe_);
  EXPECT_FALSE(host_message_pipe_);
  EXPECT_EQ(CHANNEL_CONNECTION_ERROR, error_);

  client_transport_->GetChannelFactory()->CancelChannelCreation(
      kChannelName);
  host_transport_->GetChannelFactory()->CancelChannelCreation(
      kChannelName);
}

TEST_F(IceTransportTest, TestCancelChannelCreation) {
  InitializeConnection();

  client_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  client_transport_->GetChannelFactory()->CancelChannelCreation(
      kChannelName);

  EXPECT_TRUE(!client_message_pipe_.get());
}

// Verify that we can still connect even when there is a delay in signaling
// messages delivery.
TEST_F(IceTransportTest, TestDelayedSignaling) {
  transport_info_delay_ = base::TimeDelta::FromMilliseconds(100);

  InitializeConnection();

  client_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  host_transport_->GetChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  WaitUntilConnected();

  MessagePipeConnectionTester tester(host_message_pipe_.get(),
                                     client_message_pipe_.get(), kMessageSize,
                                     kMessages);
  tester.RunAndCheckResults();
}


}  // namespace protocol
}  // namespace remoting
