// Copyright 2013 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 "ppapi/tests/test_host_resolver.h"

#include "ppapi/cpp/host_resolver.h"
#include "ppapi/cpp/net_address.h"
#include "ppapi/cpp/tcp_socket.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(HostResolver);

TestHostResolver::TestHostResolver(TestingInstance* instance)
    : TestCase(instance) {
}

bool TestHostResolver::Init() {
  bool host_resolver_is_available = pp::HostResolver::IsAvailable();
  if (!host_resolver_is_available)
    instance_->AppendError("PPB_HostResolver interface not available");

  bool tcp_socket_is_available = pp::TCPSocket::IsAvailable();
  if (!tcp_socket_is_available)
    instance_->AppendError("PPB_TCPSocket interface not available");

  bool init_host_port =
      GetLocalHostPort(instance_->pp_instance(), &host_, &port_);
  if (!init_host_port)
    instance_->AppendError("Can't init host and port");

  return host_resolver_is_available &&
      tcp_socket_is_available &&
      init_host_port &&
      CheckTestingInterface() &&
      EnsureRunningOverHTTP();
}

void TestHostResolver::RunTests(const std::string& filter) {
  RUN_TEST(Empty, filter);
  RUN_CALLBACK_TEST(TestHostResolver, Resolve, filter);
  RUN_CALLBACK_TEST(TestHostResolver, ResolveIPv4, filter);
}

std::string TestHostResolver::SyncConnect(
    pp::TCPSocket* socket,
    const pp::NetAddress& address) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(socket->Connect(address, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  PASS();
}

std::string TestHostResolver::SyncRead(pp::TCPSocket* socket,
                                       char* buffer,
                                       int32_t num_bytes,
                                       int32_t* bytes_read) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(
      socket->Read(buffer, num_bytes, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(num_bytes, callback.result());
  *bytes_read = callback.result();
  PASS();
}

std::string TestHostResolver::SyncWrite(pp::TCPSocket* socket,
                                        const char* buffer,
                                        int32_t num_bytes,
                                        int32_t* bytes_written) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(
      socket->Write(buffer, num_bytes, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(num_bytes, callback.result());
  *bytes_written = callback.result();
  PASS();
}

std::string TestHostResolver::CheckHTTPResponse(pp::TCPSocket* socket,
                                                const std::string& request,
                                                const std::string& response) {
  int32_t rv = 0;
  ASSERT_SUBTEST_SUCCESS(
      SyncWrite(socket, request.c_str(), static_cast<int32_t>(request.size()),
                &rv));
  std::vector<char> response_buffer(response.size());
  ASSERT_SUBTEST_SUCCESS(
      SyncRead(socket, &response_buffer[0],
               static_cast<int32_t>(response.size()), &rv));
  std::string actual_response(&response_buffer[0], rv);
  if (response != actual_response) {
    return "CheckHTTPResponse failed, expected: " + response +
        ", actual: " + actual_response;
  }
  PASS();
}

std::string TestHostResolver::SyncResolve(
    pp::HostResolver* host_resolver,
    const std::string& host,
    uint16_t port,
    const PP_HostResolver_Hint& hint) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(
      host_resolver->Resolve(host.c_str(), port, hint, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  PASS();
}

std::string TestHostResolver::ParameterizedTestResolve(
    const PP_HostResolver_Hint& hint) {
  pp::HostResolver host_resolver(instance_);

  ASSERT_SUBTEST_SUCCESS(SyncResolve(&host_resolver, host_, port_, hint));

  size_t size = host_resolver.GetNetAddressCount();
  ASSERT_TRUE(size >= 1);

  pp::NetAddress address;
  for (size_t i = 0; i < size; ++i) {
    address = host_resolver.GetNetAddress(static_cast<uint32_t>(i));
    ASSERT_NE(0, address.pp_resource());

    pp::TCPSocket socket(instance_);
    ASSERT_SUBTEST_SUCCESS(SyncConnect(&socket, address));
    ASSERT_SUBTEST_SUCCESS(CheckHTTPResponse(&socket,
                                             "GET / HTTP/1.0\r\n\r\n",
                                             "HTTP"));
    socket.Close();
  }

  address = host_resolver.GetNetAddress(static_cast<uint32_t>(size));
  ASSERT_EQ(0, address.pp_resource());
  pp::Var canonical_name = host_resolver.GetCanonicalName();
  ASSERT_TRUE(canonical_name.is_string());

  ASSERT_SUBTEST_SUCCESS(SyncResolve(&host_resolver, canonical_name.AsString(),
                                     port_, hint));
  size = host_resolver.GetNetAddressCount();
  ASSERT_TRUE(size >= 1);

  PASS();
}

std::string TestHostResolver::TestEmpty() {
  pp::HostResolver host_resolver(instance_);
  ASSERT_EQ(0, host_resolver.GetNetAddressCount());
  pp::NetAddress address = host_resolver.GetNetAddress(0);
  ASSERT_EQ(0, address.pp_resource());

  PASS();
}

std::string TestHostResolver::TestResolve() {
  PP_HostResolver_Hint hint;
  hint.family = PP_NETADDRESS_FAMILY_UNSPECIFIED;
  hint.flags = PP_HOSTRESOLVER_FLAG_CANONNAME;
  return ParameterizedTestResolve(hint);
}

std::string TestHostResolver::TestResolveIPv4() {
  PP_HostResolver_Hint hint;
  hint.family = PP_NETADDRESS_FAMILY_IPV4;
  hint.flags = PP_HOSTRESOLVER_FLAG_CANONNAME;
  return ParameterizedTestResolve(hint);
}
