// Copyright (c) 2012 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_private.h"

#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/private/host_resolver_private.h"
#include "ppapi/cpp/private/tcp_socket_private.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(HostResolverPrivate);

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

bool TestHostResolverPrivate::Init() {
  bool host_resolver_private_is_available =
      pp::HostResolverPrivate::IsAvailable();
  if (!host_resolver_private_is_available)
    instance_->AppendError("PPB_HostResolver_Private interface not available");

  bool tcp_socket_private_is_available = pp::TCPSocketPrivate::IsAvailable();
  if (!tcp_socket_private_is_available)
    instance_->AppendError("PPB_TCPSocket_Private 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_private_is_available &&
      tcp_socket_private_is_available &&
      init_host_port &&
      CheckTestingInterface() &&
      EnsureRunningOverHTTP();
}

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

std::string TestHostResolverPrivate::SyncConnect(pp::TCPSocketPrivate* socket,
                                                 const std::string& host,
                                                 uint16_t port) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(
     socket->Connect(host.c_str(), port, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  PASS();
}

std::string TestHostResolverPrivate::SyncConnect(
    pp::TCPSocketPrivate* socket,
    const PP_NetAddress_Private& address) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(
      socket->ConnectWithNetAddress(&address, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  PASS();
}

std::string TestHostResolverPrivate::SyncRead(pp::TCPSocketPrivate* 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 TestHostResolverPrivate::SyncWrite(pp::TCPSocketPrivate* 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 TestHostResolverPrivate::CheckHTTPResponse(
    pp::TCPSocketPrivate* socket,
    const std::string& request,
    const std::string& response) {
  int32_t rv = 0;
  ASSERT_SUBTEST_SUCCESS(
      SyncWrite(socket, request.c_str(), request.size(), &rv));
  std::vector<char> response_buffer(response.size());
  ASSERT_SUBTEST_SUCCESS(
      SyncRead(socket, &response_buffer[0], 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 TestHostResolverPrivate::SyncResolve(
    pp::HostResolverPrivate* host_resolver,
    const std::string& host,
    uint16_t port,
    const PP_HostResolver_Private_Hint& hint) {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(
      host_resolver->Resolve(host, port, hint, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  PASS();
}

std::string TestHostResolverPrivate::TestEmpty() {
  pp::HostResolverPrivate host_resolver(instance_);
  ASSERT_EQ(0, host_resolver.GetSize());
  PP_NetAddress_Private address;
  ASSERT_FALSE(host_resolver.GetNetAddress(0, &address));

  PASS();
}

std::string TestHostResolverPrivate::ParametrizedTestResolve(
    const PP_HostResolver_Private_Hint &hint) {
  pp::HostResolverPrivate host_resolver(instance_);

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

  const size_t size = host_resolver.GetSize();
  ASSERT_TRUE(size >= 1);

  PP_NetAddress_Private address;
  for (size_t i = 0; i < size; ++i) {
    ASSERT_TRUE(host_resolver.GetNetAddress(i, &address));

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

  ASSERT_FALSE(host_resolver.GetNetAddress(size, &address));
  pp::Var canonical_name = host_resolver.GetCanonicalName();
  ASSERT_TRUE(canonical_name.is_string());
  pp::TCPSocketPrivate socket(instance_);
  ASSERT_SUBTEST_SUCCESS(SyncConnect(&socket,
                                     canonical_name.AsString(),
                                     port_));
  ASSERT_SUBTEST_SUCCESS(CheckHTTPResponse(&socket,
                                           "GET / HTTP/1.0\r\n\r\n",
                                           "HTTP"));
  socket.Disconnect();

  PASS();
}

std::string TestHostResolverPrivate::TestResolve() {
  PP_HostResolver_Private_Hint hint;
  hint.family = PP_NETADDRESSFAMILY_PRIVATE_UNSPECIFIED;
  hint.flags = PP_HOST_RESOLVER_PRIVATE_FLAGS_CANONNAME;
  return ParametrizedTestResolve(hint);
}

std::string TestHostResolverPrivate::TestResolveIPv4() {
  PP_HostResolver_Private_Hint hint;
  hint.family = PP_NETADDRESSFAMILY_PRIVATE_IPV4;
  hint.flags = PP_HOST_RESOLVER_PRIVATE_FLAGS_CANONNAME;
  return ParametrizedTestResolve(hint);
}
