// 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_utils.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_MSC_VER)
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/net_address.h"
#include "ppapi/cpp/private/host_resolver_private.h"
#include "ppapi/cpp/private/net_address_private.h"
#include "ppapi/cpp/var.h"

namespace {

bool IsBigEndian() {
  union {
    uint32_t integer32;
    uint8_t integer8[4];
  } data = { 0x01020304 };

  return data.integer8[0] == 1;
}

}  // namespace

const int kActionTimeoutMs = 10000;

const PPB_Testing_Private* GetTestingInterface() {
  static const PPB_Testing_Private* g_testing_interface =
      static_cast<const PPB_Testing_Private*>(
          pp::Module::Get()->GetBrowserInterface(
              PPB_TESTING_PRIVATE_INTERFACE));
  return g_testing_interface;
}

std::string ReportError(const char* method, int32_t error) {
  char error_as_string[12];
  sprintf(error_as_string, "%d", static_cast<int>(error));
  std::string result = method + std::string(" failed with error: ") +
      error_as_string;
  return result;
}

void PlatformSleep(int duration_ms) {
#if defined(_MSC_VER)
  ::Sleep(duration_ms);
#else
  usleep(duration_ms * 1000);
#endif
}

bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port) {
  if (!host || !port)
    return false;

  const PPB_Testing_Private* testing = GetTestingInterface();
  if (!testing)
    return false;

  PP_URLComponents_Dev components;
  pp::Var pp_url(pp::PASS_REF,
                 testing->GetDocumentURL(instance, &components));
  if (!pp_url.is_string())
    return false;
  std::string url = pp_url.AsString();

  if (components.host.len < 0)
    return false;
  host->assign(url.substr(components.host.begin, components.host.len));

  if (components.port.len <= 0)
    return false;

  int i = atoi(url.substr(components.port.begin, components.port.len).c_str());
  if (i < 0 || i > 65535)
    return false;
  *port = static_cast<uint16_t>(i);

  return true;
}

uint16_t ConvertFromNetEndian16(uint16_t x) {
  if (IsBigEndian())
    return x;
  else
    return (x << 8) | (x >> 8);
}

uint16_t ConvertToNetEndian16(uint16_t x) {
  if (IsBigEndian())
    return x;
  else
    return (x << 8) | (x >> 8);
}

bool EqualNetAddress(const pp::NetAddress& addr1, const pp::NetAddress& addr2) {
  if (addr1.GetFamily() == PP_NETADDRESS_FAMILY_UNSPECIFIED ||
      addr2.GetFamily() == PP_NETADDRESS_FAMILY_UNSPECIFIED) {
    return false;
  }

  if (addr1.GetFamily() == PP_NETADDRESS_FAMILY_IPV4) {
    PP_NetAddress_IPv4 ipv4_addr1, ipv4_addr2;
    if (!addr1.DescribeAsIPv4Address(&ipv4_addr1) ||
        !addr2.DescribeAsIPv4Address(&ipv4_addr2)) {
      return false;
    }

    return ipv4_addr1.port == ipv4_addr2.port &&
           !memcmp(ipv4_addr1.addr, ipv4_addr2.addr, sizeof(ipv4_addr1.addr));
  } else {
    PP_NetAddress_IPv6 ipv6_addr1, ipv6_addr2;
    if (!addr1.DescribeAsIPv6Address(&ipv6_addr1) ||
        !addr2.DescribeAsIPv6Address(&ipv6_addr2)) {
      return false;
    }

    return ipv6_addr1.port == ipv6_addr2.port &&
           !memcmp(ipv6_addr1.addr, ipv6_addr2.addr, sizeof(ipv6_addr1.addr));
  }
}

bool ResolveHost(PP_Instance instance,
                 const std::string& host,
                 uint16_t port,
                 pp::NetAddress* addr) {
  // TODO(yzshen): Change to use the public host resolver once it is supported.
  pp::InstanceHandle instance_handle(instance);
  pp::HostResolverPrivate host_resolver(instance_handle);
  PP_HostResolver_Private_Hint hint =
      { PP_NETADDRESSFAMILY_PRIVATE_UNSPECIFIED, 0 };

  TestCompletionCallback callback(instance);
  callback.WaitForResult(
      host_resolver.Resolve(host, port, hint, callback.GetCallback()));

  PP_NetAddress_Private addr_private;
  if (callback.result() != PP_OK || host_resolver.GetSize() == 0 ||
      !host_resolver.GetNetAddress(0, &addr_private)) {
    return false;
  }

  switch (pp::NetAddressPrivate::GetFamily(addr_private)) {
    case PP_NETADDRESSFAMILY_PRIVATE_IPV4: {
      PP_NetAddress_IPv4 ipv4_addr;
      ipv4_addr.port = ConvertToNetEndian16(
          pp::NetAddressPrivate::GetPort(addr_private));
      if (!pp::NetAddressPrivate::GetAddress(addr_private, ipv4_addr.addr,
                                             sizeof(ipv4_addr.addr))) {
        return false;
      }
      *addr = pp::NetAddress(instance_handle, ipv4_addr);
      return true;
    }
    case PP_NETADDRESSFAMILY_PRIVATE_IPV6: {
      PP_NetAddress_IPv6 ipv6_addr;
      ipv6_addr.port = ConvertToNetEndian16(
          pp::NetAddressPrivate::GetPort(addr_private));
      if (!pp::NetAddressPrivate::GetAddress(addr_private, ipv6_addr.addr,
                                             sizeof(ipv6_addr.addr))) {
        return false;
      }
      *addr = pp::NetAddress(instance_handle, ipv6_addr);
      return true;
    }
    default: {
      return false;
    }
  }
}

bool ReplacePort(PP_Instance instance,
                 const pp::NetAddress& input_addr,
                 uint16_t port,
                 pp::NetAddress* output_addr) {
  switch (input_addr.GetFamily()) {
    case PP_NETADDRESS_FAMILY_IPV4: {
      PP_NetAddress_IPv4 ipv4_addr;
      if (!input_addr.DescribeAsIPv4Address(&ipv4_addr))
        return false;
      ipv4_addr.port = ConvertToNetEndian16(port);
      *output_addr = pp::NetAddress(pp::InstanceHandle(instance), ipv4_addr);
      return true;
    }
    case PP_NETADDRESS_FAMILY_IPV6: {
      PP_NetAddress_IPv6 ipv6_addr;
      if (!input_addr.DescribeAsIPv6Address(&ipv6_addr))
        return false;
      ipv6_addr.port = ConvertToNetEndian16(port);
      *output_addr = pp::NetAddress(pp::InstanceHandle(instance), ipv6_addr);
      return true;
    }
    default: {
      return false;
    }
  }
}

uint16_t GetPort(const pp::NetAddress& addr) {
  switch (addr.GetFamily()) {
    case PP_NETADDRESS_FAMILY_IPV4: {
      PP_NetAddress_IPv4 ipv4_addr;
      if (!addr.DescribeAsIPv4Address(&ipv4_addr))
        return 0;
      return ConvertFromNetEndian16(ipv4_addr.port);
    }
    case PP_NETADDRESS_FAMILY_IPV6: {
      PP_NetAddress_IPv6 ipv6_addr;
      if (!addr.DescribeAsIPv6Address(&ipv6_addr))
        return 0;
      return ConvertFromNetEndian16(ipv6_addr.port);
    }
    default: {
      return 0;
    }
  }
}

void NestedEvent::Wait() {
  PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
  // Don't allow nesting more than once; it doesn't work with the code as-is,
  // and probably is a bad idea most of the time anyway.
  PP_DCHECK(!waiting_);
  if (signalled_)
    return;
  waiting_ = true;
  while (!signalled_)
    GetTestingInterface()->RunMessageLoop(instance_);
  waiting_ = false;
}

void NestedEvent::Signal() {
  if (pp::Module::Get()->core()->IsMainThread())
    SignalOnMainThread();
  else
    PostSignal(0);
}

void NestedEvent::PostSignal(int32_t wait_ms) {
  pp::Module::Get()->core()->CallOnMainThread(
      wait_ms,
      pp::CompletionCallback(&SignalThunk, this),
      0);
}

void NestedEvent::Reset() {
  PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
  // It doesn't make sense to reset when we're still waiting.
  PP_DCHECK(!waiting_);
  signalled_ = false;
}

void NestedEvent::SignalOnMainThread() {
  PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
  signalled_ = true;
  if (waiting_)
    GetTestingInterface()->QuitMessageLoop(instance_);
}

void NestedEvent::SignalThunk(void* event, int32_t /* result */) {
  static_cast<NestedEvent*>(event)->SignalOnMainThread();
}

TestCompletionCallback::TestCompletionCallback(PP_Instance instance)
    : wait_for_result_called_(false),
      have_result_(false),
      result_(PP_OK_COMPLETIONPENDING),
      // TODO(dmichael): The default should probably be PP_REQUIRED, but this is
      //                 what the tests currently expect.
      callback_type_(PP_OPTIONAL),
      post_quit_task_(false),
      instance_(instance),
      delegate_(NULL) {
}

TestCompletionCallback::TestCompletionCallback(PP_Instance instance,
                                               bool force_async)
    : wait_for_result_called_(false),
      have_result_(false),
      result_(PP_OK_COMPLETIONPENDING),
      callback_type_(force_async ? PP_REQUIRED : PP_OPTIONAL),
      post_quit_task_(false),
      instance_(instance),
      delegate_(NULL) {
}

TestCompletionCallback::TestCompletionCallback(PP_Instance instance,
                                               CallbackType callback_type)
    : wait_for_result_called_(false),
      have_result_(false),
      result_(PP_OK_COMPLETIONPENDING),
      callback_type_(callback_type),
      post_quit_task_(false),
      instance_(instance),
      delegate_(NULL) {
}

void TestCompletionCallback::WaitForResult(int32_t result) {
  PP_DCHECK(!wait_for_result_called_);
  wait_for_result_called_ = true;
  errors_.clear();
  if (result == PP_OK_COMPLETIONPENDING) {
    if (!have_result_) {
      post_quit_task_ = true;
      RunMessageLoop();
    }
    if (callback_type_ == PP_BLOCKING) {
      errors_.assign(
          ReportError("TestCompletionCallback: Call did not run synchronously "
                      "when passed a blocking completion callback!",
                      result_));
      return;
    }
  } else {
    result_ = result;
    have_result_ = true;
    if (callback_type_ == PP_REQUIRED) {
      errors_.assign(
          ReportError("TestCompletionCallback: Call ran synchronously when "
                      "passed a required completion callback!",
                      result_));
      return;
    }
  }
  PP_DCHECK(have_result_ == true);
}

void TestCompletionCallback::WaitForAbortResult(int32_t result) {
  WaitForResult(result);
  int32_t final_result = result_;
  if (result == PP_OK_COMPLETIONPENDING) {
    if (final_result != PP_ERROR_ABORTED) {
      errors_.assign(
          ReportError("TestCompletionCallback: Expected PP_ERROR_ABORTED or "
                      "PP_OK. Ran asynchronously.",
                      final_result));
      return;
    }
  } else if (result < PP_OK) {
    errors_.assign(
        ReportError("TestCompletionCallback: Expected PP_ERROR_ABORTED or "
                    "non-error response. Ran synchronously.",
                    result));
    return;
  }
}

pp::CompletionCallback TestCompletionCallback::GetCallback() {
  Reset();
  int32_t flags = 0;
  if (callback_type_ == PP_BLOCKING)
    return pp::CompletionCallback();
  else if (callback_type_ == PP_OPTIONAL)
    flags = PP_COMPLETIONCALLBACK_FLAG_OPTIONAL;
  target_loop_ = pp::MessageLoop::GetCurrent();
  return pp::CompletionCallback(&TestCompletionCallback::Handler,
                                const_cast<TestCompletionCallback*>(this),
                                flags);
}

void TestCompletionCallback::Reset() {
  wait_for_result_called_ = false;
  result_ = PP_OK_COMPLETIONPENDING;
  have_result_ = false;
  post_quit_task_ = false;
  delegate_ = NULL;
  errors_.clear();
}

// static
void TestCompletionCallback::Handler(void* user_data, int32_t result) {
  TestCompletionCallback* callback =
      static_cast<TestCompletionCallback*>(user_data);
  // If this check fails, it means that the callback was invoked twice or that
  // the PPAPI call completed synchronously, but also ran the callback.
  PP_DCHECK(!callback->have_result_);
  callback->result_ = result;
  callback->have_result_ = true;
  if (callback->delegate_)
    callback->delegate_->OnCallback(user_data, result);
  if (callback->post_quit_task_) {
    callback->post_quit_task_ = false;
    callback->QuitMessageLoop();
  }
  if (callback->target_loop_ != pp::MessageLoop::GetCurrent()) {
    // Note, in-process, loop_ and GetCurrent() will both be NULL, so should
    // still be equal.
    callback->errors_.assign(
        ReportError("TestCompletionCallback: Callback ran on the wrong message "
                    "loop!",
                    result));
  }
}

void TestCompletionCallback::RunMessageLoop() {
  pp::MessageLoop loop(pp::MessageLoop::GetCurrent());
  // If we don't have a message loop, we're probably running in process, where
  // PPB_MessageLoop is not supported. Just use the Testing message loop.
  if (loop.is_null() || loop == pp::MessageLoop::GetForMainThread())
    GetTestingInterface()->RunMessageLoop(instance_);
  else
    loop.Run();
}

void TestCompletionCallback::QuitMessageLoop() {
  pp::MessageLoop loop(pp::MessageLoop::GetCurrent());
  // If we don't have a message loop, we're probably running in process, where
  // PPB_MessageLoop is not supported. Just use the Testing message loop.
  if (loop.is_null() || loop == pp::MessageLoop::GetForMainThread()) {
    GetTestingInterface()->QuitMessageLoop(instance_);
  } else {
    const bool should_quit = false;
    loop.PostQuit(should_quit);
  }
}
