// 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 "net/dns/host_resolver_mojo.h"

#include <memory>
#include <string>
#include <utility>

#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/address_list.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/base/test_completion_callback.h"
#include "net/log/net_log_with_source.h"
#include "net/test/event_waiter.h"
#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using net::test::IsError;
using net::test::IsOk;

namespace net {
namespace {

void Fail(int result) {
  FAIL() << "Unexpected callback called with error " << result;
}

class MockMojoHostResolverRequest {
 public:
  MockMojoHostResolverRequest(interfaces::HostResolverRequestClientPtr client,
                              const base::Closure& error_callback);
  void OnConnectionError();

 private:
  interfaces::HostResolverRequestClientPtr client_;
  const base::Closure error_callback_;
};

MockMojoHostResolverRequest::MockMojoHostResolverRequest(
    interfaces::HostResolverRequestClientPtr client,
    const base::Closure& error_callback)
    : client_(std::move(client)), error_callback_(error_callback) {
  client_.set_connection_error_handler(base::Bind(
      &MockMojoHostResolverRequest::OnConnectionError, base::Unretained(this)));
}

void MockMojoHostResolverRequest::OnConnectionError() {
  error_callback_.Run();
}

struct HostResolverAction {
  enum Action {
    COMPLETE,
    DROP,
    RETAIN,
  };

  static HostResolverAction ReturnError(Error error) {
    HostResolverAction result;
    result.error = error;
    return result;
  }

  static HostResolverAction ReturnResult(const AddressList& address_list) {
    HostResolverAction result;
    result.addresses = address_list;
    return result;
  }

  static HostResolverAction DropRequest() {
    HostResolverAction result;
    result.action = DROP;
    return result;
  }

  static HostResolverAction RetainRequest() {
    HostResolverAction result;
    result.action = RETAIN;
    return result;
  }

  Action action = COMPLETE;
  AddressList addresses;
  Error error = OK;
};

class MockMojoHostResolver : public HostResolverMojo::Impl {
 public:
  explicit MockMojoHostResolver(
      const base::Closure& request_connection_error_callback);
  ~MockMojoHostResolver() override;

  void AddAction(HostResolverAction action);

  const std::vector<HostResolver::RequestInfo>& requests() {
    return requests_received_;
  }

  void ResolveDns(std::unique_ptr<HostResolver::RequestInfo> request_info,
                  interfaces::HostResolverRequestClientPtr client) override;

 private:
  std::vector<HostResolverAction> actions_;
  size_t results_returned_ = 0;
  std::vector<HostResolver::RequestInfo> requests_received_;
  const base::Closure request_connection_error_callback_;
  std::vector<std::unique_ptr<MockMojoHostResolverRequest>> requests_;
};

MockMojoHostResolver::MockMojoHostResolver(
    const base::Closure& request_connection_error_callback)
    : request_connection_error_callback_(request_connection_error_callback) {
}

MockMojoHostResolver::~MockMojoHostResolver() {
  EXPECT_EQ(results_returned_, actions_.size());
}

void MockMojoHostResolver::AddAction(HostResolverAction action) {
  actions_.push_back(std::move(action));
}

void MockMojoHostResolver::ResolveDns(
    std::unique_ptr<HostResolver::RequestInfo> request_info,
    interfaces::HostResolverRequestClientPtr client) {
  requests_received_.push_back(std::move(*request_info));
  ASSERT_LE(results_returned_, actions_.size());
  switch (actions_[results_returned_].action) {
    case HostResolverAction::COMPLETE:
      client->ReportResult(actions_[results_returned_].error,
                           std::move(actions_[results_returned_].addresses));
      break;
    case HostResolverAction::RETAIN:
      requests_.push_back(std::make_unique<MockMojoHostResolverRequest>(
          std::move(client), request_connection_error_callback_));
      break;
    case HostResolverAction::DROP:
      client.reset();
      break;
  }
  results_returned_++;
}

}  // namespace

class HostResolverMojoTest : public testing::Test {
 protected:
  enum class ConnectionErrorSource {
    REQUEST,
  };
  using Waiter = EventWaiter<ConnectionErrorSource>;

  void SetUp() override {
    mock_resolver_.reset(new MockMojoHostResolver(
        base::Bind(&Waiter::NotifyEvent, base::Unretained(&waiter_),
                   ConnectionErrorSource::REQUEST)));
    resolver_.reset(new HostResolverMojo(mock_resolver_.get()));
  }

  int Resolve(const HostResolver::RequestInfo& request_info,
              AddressList* result) {
    TestCompletionCallback callback;
    return callback.GetResult(
        resolver_->Resolve(request_info, DEFAULT_PRIORITY, result,
                           callback.callback(), &request_, NetLogWithSource()));
  }

  std::unique_ptr<MockMojoHostResolver> mock_resolver_;

  std::unique_ptr<HostResolverMojo> resolver_;

  std::unique_ptr<HostResolver::Request> request_;

  Waiter waiter_;
};

TEST_F(HostResolverMojoTest, Basic) {
  AddressList address_list;
  IPAddress address(1, 2, 3, 4);
  address_list.push_back(IPEndPoint(address, 12345));
  address_list.push_back(
      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
  mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:12345"));
  AddressList result;
  EXPECT_THAT(Resolve(request_info, &result), IsOk());
  ASSERT_EQ(2u, result.size());
  EXPECT_EQ(address_list[0], result[0]);
  EXPECT_EQ(address_list[1], result[1]);

  ASSERT_EQ(1u, mock_resolver_->requests().size());
  const HostResolver::RequestInfo& request = mock_resolver_->requests()[0];
  EXPECT_EQ("example.com", request.hostname());
  EXPECT_EQ(12345, request.port());
  EXPECT_EQ(ADDRESS_FAMILY_UNSPECIFIED, request.address_family());
  EXPECT_FALSE(request.is_my_ip_address());
}

TEST_F(HostResolverMojoTest, ResolveCachedResult) {
  AddressList address_list;
  IPAddress address(1, 2, 3, 4);
  address_list.push_back(IPEndPoint(address, 12345));
  address_list.push_back(
      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
  mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:12345"));
  AddressList result;
  ASSERT_THAT(Resolve(request_info, &result), IsOk());
  ASSERT_EQ(1u, mock_resolver_->requests().size());

  result.clear();
  request_info.set_host_port_pair(HostPortPair::FromString("example.com:6789"));
  EXPECT_THAT(Resolve(request_info, &result), IsOk());
  ASSERT_EQ(2u, result.size());
  address_list.clear();
  address_list.push_back(IPEndPoint(address, 6789));
  address_list.push_back(
      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 6789));
  EXPECT_EQ(address_list[0], result[0]);
  EXPECT_EQ(address_list[1], result[1]);
  EXPECT_EQ(1u, mock_resolver_->requests().size());

  mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
  result.clear();
  request_info.set_allow_cached_response(false);
  EXPECT_THAT(Resolve(request_info, &result), IsOk());
  ASSERT_EQ(2u, result.size());
  EXPECT_EQ(address_list[0], result[0]);
  EXPECT_EQ(address_list[1], result[1]);
  EXPECT_EQ(2u, mock_resolver_->requests().size());
}

TEST_F(HostResolverMojoTest, Multiple) {
  AddressList address_list;
  IPAddress address(1, 2, 3, 4);
  address_list.push_back(IPEndPoint(address, 12345));
  mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
  mock_resolver_->AddAction(
      HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED));
  HostResolver::RequestInfo request_info1(
      HostPortPair::FromString("example.com:12345"));
  request_info1.set_address_family(ADDRESS_FAMILY_IPV4);
  request_info1.set_is_my_ip_address(true);
  HostResolver::RequestInfo request_info2(
      HostPortPair::FromString("example.org:80"));
  request_info2.set_address_family(ADDRESS_FAMILY_IPV6);
  AddressList result1;
  AddressList result2;
  std::unique_ptr<HostResolver::Request> request1;
  std::unique_ptr<HostResolver::Request> request2;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  ASSERT_EQ(ERR_IO_PENDING, resolver_->Resolve(request_info1, DEFAULT_PRIORITY,
                                               &result1, callback1.callback(),
                                               &request1, NetLogWithSource()));
  ASSERT_EQ(ERR_IO_PENDING, resolver_->Resolve(request_info2, DEFAULT_PRIORITY,
                                               &result2, callback2.callback(),
                                               &request2, NetLogWithSource()));
  EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
  EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING),
              IsError(ERR_NAME_NOT_RESOLVED));
  ASSERT_EQ(1u, result1.size());
  EXPECT_EQ(address_list[0], result1[0]);
  ASSERT_EQ(0u, result2.size());

  ASSERT_EQ(2u, mock_resolver_->requests().size());
  const HostResolver::RequestInfo& info1 = mock_resolver_->requests()[0];
  EXPECT_EQ("example.com", info1.hostname());
  EXPECT_EQ(12345, info1.port());
  EXPECT_EQ(ADDRESS_FAMILY_IPV4, info1.address_family());
  EXPECT_TRUE(info1.is_my_ip_address());
  const HostResolver::RequestInfo& info2 = mock_resolver_->requests()[1];
  EXPECT_EQ("example.org", info2.hostname());
  EXPECT_EQ(80, info2.port());
  EXPECT_EQ(ADDRESS_FAMILY_IPV6, info2.address_family());
  EXPECT_FALSE(info2.is_my_ip_address());
}

TEST_F(HostResolverMojoTest, Error) {
  mock_resolver_->AddAction(
      HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED));
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:8080"));
  request_info.set_address_family(ADDRESS_FAMILY_IPV4);
  AddressList result;
  EXPECT_THAT(Resolve(request_info, &result), IsError(ERR_NAME_NOT_RESOLVED));
  EXPECT_TRUE(result.empty());

  ASSERT_EQ(1u, mock_resolver_->requests().size());
  const HostResolver::RequestInfo& request = mock_resolver_->requests()[0];
  EXPECT_EQ("example.com", request.hostname());
  EXPECT_EQ(8080, request.port());
  EXPECT_EQ(ADDRESS_FAMILY_IPV4, request.address_family());
  EXPECT_FALSE(request.is_my_ip_address());
}

TEST_F(HostResolverMojoTest, EmptyResult) {
  mock_resolver_->AddAction(HostResolverAction::ReturnError(OK));
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:8080"));
  AddressList result;
  EXPECT_THAT(Resolve(request_info, &result), IsOk());
  EXPECT_TRUE(result.empty());

  ASSERT_EQ(1u, mock_resolver_->requests().size());
}

TEST_F(HostResolverMojoTest, Cancel) {
  mock_resolver_->AddAction(HostResolverAction::RetainRequest());
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:80"));
  request_info.set_address_family(ADDRESS_FAMILY_IPV6);
  AddressList result;
  std::unique_ptr<HostResolver::Request> request;
  resolver_->Resolve(request_info, DEFAULT_PRIORITY, &result, base::Bind(&Fail),
                     &request, NetLogWithSource());
  request.reset();
  waiter_.WaitForEvent(ConnectionErrorSource::REQUEST);
  EXPECT_TRUE(result.empty());

  ASSERT_EQ(1u, mock_resolver_->requests().size());
  const HostResolver::RequestInfo& info1 = mock_resolver_->requests()[0];
  EXPECT_EQ("example.com", info1.hostname());
  EXPECT_EQ(80, info1.port());
  EXPECT_EQ(ADDRESS_FAMILY_IPV6, info1.address_family());
  EXPECT_FALSE(info1.is_my_ip_address());
}

TEST_F(HostResolverMojoTest, ImplDropsClientConnection) {
  mock_resolver_->AddAction(HostResolverAction::DropRequest());
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:1"));
  AddressList result;
  EXPECT_THAT(Resolve(request_info, &result), IsError(ERR_FAILED));
  EXPECT_TRUE(result.empty());

  ASSERT_EQ(1u, mock_resolver_->requests().size());
  const HostResolver::RequestInfo& info2 = mock_resolver_->requests()[0];
  EXPECT_EQ("example.com", info2.hostname());
  EXPECT_EQ(1, info2.port());
  EXPECT_EQ(ADDRESS_FAMILY_UNSPECIFIED, info2.address_family());
  EXPECT_FALSE(info2.is_my_ip_address());
}

TEST_F(HostResolverMojoTest, ResolveFromCache_Miss) {
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:8080"));
  AddressList result;
  EXPECT_EQ(ERR_DNS_CACHE_MISS, resolver_->ResolveFromCache(
                                    request_info, &result, NetLogWithSource()));
  EXPECT_TRUE(result.empty());
}

TEST_F(HostResolverMojoTest, ResolveFromCache_Hit) {
  AddressList address_list;
  IPAddress address(1, 2, 3, 4);
  address_list.push_back(IPEndPoint(address, 12345));
  address_list.push_back(
      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
  mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:12345"));
  AddressList result;
  ASSERT_THAT(Resolve(request_info, &result), IsOk());
  EXPECT_EQ(1u, mock_resolver_->requests().size());

  result.clear();
  EXPECT_EQ(OK, resolver_->ResolveFromCache(request_info, &result,
                                            NetLogWithSource()));
  ASSERT_EQ(2u, result.size());
  EXPECT_EQ(address_list[0], result[0]);
  EXPECT_EQ(address_list[1], result[1]);
  EXPECT_EQ(1u, mock_resolver_->requests().size());
}

TEST_F(HostResolverMojoTest, ResolveFromCache_CacheNotAllowed) {
  AddressList address_list;
  IPAddress address(1, 2, 3, 4);
  address_list.push_back(IPEndPoint(address, 12345));
  address_list.push_back(
      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
  mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
  HostResolver::RequestInfo request_info(
      HostPortPair::FromString("example.com:12345"));
  AddressList result;
  ASSERT_THAT(Resolve(request_info, &result), IsOk());
  EXPECT_EQ(1u, mock_resolver_->requests().size());

  result.clear();
  request_info.set_allow_cached_response(false);
  EXPECT_EQ(ERR_DNS_CACHE_MISS, resolver_->ResolveFromCache(
                                    request_info, &result, NetLogWithSource()));
  EXPECT_TRUE(result.empty());
}

TEST_F(HostResolverMojoTest, GetHostCache) {
  EXPECT_TRUE(resolver_->GetHostCache());
}

}  // namespace net
