// 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 "base/bind.h"
#include "base/lazy_instance.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "mojo/common/message_pump_mojo.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
#include "mojo/services/network/public/interfaces/net_address.mojom.h"
#include "mojo/services/network/public/interfaces/host_resolver.mojom.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/mojo/src/mojo/public/cpp/application/application_connection.h"
#include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h"
#include "third_party/mojo/src/mojo/public/cpp/application/application_test_base.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/callback.h"

namespace mojo {

class HostResolverTestHelper {
 public:
  static bool Match4(uint8_t* expected_ipv4, const NetAddressPtr& address) {
    EXPECT_EQ(NET_ADDRESS_FAMILY_IPV4, address->family);
    for (size_t i = 0; i < address->ipv4->addr.size(); i++) {
      if (address->ipv4->addr[i] != expected_ipv4[i]) {
        return false;
      }
    }
    return true;
  }

  static bool Match6(uint8_t* expected_ipv6, const NetAddressPtr& address) {
    EXPECT_EQ(NET_ADDRESS_FAMILY_IPV6, address->family);
    for (size_t i = 0; i < address->ipv6->addr.size(); i++) {
      if (address->ipv6->addr[i] != expected_ipv6[i]) {
        return false;
      }
    }
    return true;
  }

  static void DebugPrint(const NetAddressPtr& address) {
    if (address->family == NET_ADDRESS_FAMILY_IPV4) {
      for (size_t i = 0; i < address->ipv4->addr.size(); i++) {
        if (i > 0) {
          printf(".");
        }
        printf("%d", address->ipv4->addr[i]);
      }
      printf("\n");
    } else if (address->family == NET_ADDRESS_FAMILY_IPV6) {
      for (size_t i = 0; i < address->ipv6->addr.size(); i++) {
        if ((i > 0) && ((i % 2) == 0)) {
          printf(":");
        }
        printf("%02X", address->ipv6->addr[i]);
      }
      printf("\n");
    } else {
      NOTREACHED();
    }
  }
};

class HostResolverImplTest : public test::ApplicationTestBase {
 public:
  HostResolverImplTest() {
  }

 protected:
  void SetUp() override {
    ApplicationTestBase::SetUp();

    ApplicationConnection* connection =
        application_impl()->ConnectToApplication("mojo:network_service");
    connection->ConnectToService(&network_service_);
  }

  NetworkServicePtr network_service_;

  DISALLOW_COPY_AND_ASSIGN(HostResolverImplTest);
};

TEST_F(HostResolverImplTest, Create) {
  HostResolverPtr host_resolver;
  network_service_->CreateHostResolver(GetProxy(&host_resolver));
}

TEST_F(HostResolverImplTest, LocalhostV4) {
  HostResolverPtr host_resolver;
  network_service_->CreateHostResolver(GetProxy(&host_resolver));
  host_resolver->GetHostAddresses("localhost", NET_ADDRESS_FAMILY_IPV4,
      [](NetworkErrorPtr error, Array<NetAddressPtr> addresses) {
    EXPECT_EQ(net::OK, error->code);
    EXPECT_GT(addresses.size(), 0U);
    uint8_t localhost4[] = {127, 0, 0, 1};
    EXPECT_TRUE(HostResolverTestHelper::Match4(localhost4, addresses[0]));
  });
  host_resolver.WaitForIncomingResponse();
}

TEST_F(HostResolverImplTest, LocalhostV6) {
  HostResolverPtr host_resolver;
  network_service_->CreateHostResolver(GetProxy(&host_resolver));
  host_resolver->GetHostAddresses("localhost", NET_ADDRESS_FAMILY_IPV6,
      [](NetworkErrorPtr error, Array<NetAddressPtr> addresses) {
    uint8_t localhost6[] = {0, 0, 0, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 1};
    if (error->code == net::OK) {
      EXPECT_EQ(net::OK, error->code);
      EXPECT_GT(addresses.size(), 0U);
      EXPECT_TRUE(HostResolverTestHelper::Match6(localhost6, addresses[0]));
    } else {
      EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, error->code);
    }
  });
  host_resolver.WaitForIncomingResponse();
}

TEST_F(HostResolverImplTest, NameNotResolved) {
  HostResolverPtr host_resolver;
  network_service_->CreateHostResolver(GetProxy(&host_resolver));
  host_resolver->GetHostAddresses("local.77778888", NET_ADDRESS_FAMILY_IPV4,
      [](NetworkErrorPtr error, Array<NetAddressPtr> addresses) {
    EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, error->code);
    EXPECT_EQ(0U, addresses.size());
  });
}

TEST_F(HostResolverImplTest, DropOnFloor) {
  HostResolverPtr host_resolver;
  network_service_->CreateHostResolver(GetProxy(&host_resolver));
  host_resolver->GetHostAddresses("localhost", NET_ADDRESS_FAMILY_IPV4,
      [](NetworkErrorPtr error, Array<NetAddressPtr> addresses) {
  });
}

}  // namespace mojo
