// 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.
//
// Tests PPB_URLRequestInfo interface.

#include "ppapi/tests/test_url_request.h"

#include <string.h>
#include <string>

#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/file_system.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(URLRequest);

namespace {
// TODO(polina): move these to test_case.h/cc since other NaCl tests use them?

const PP_Resource kInvalidResource = 0;
const PP_Instance kInvalidInstance = 0;

// These should not exist.
// The bottom 2 bits are used to differentiate between different id types.
// 00 - module, 01 - instance, 10 - resource, 11 - var.
const PP_Instance kNotAnInstance = 0xFFFFF0;
const PP_Resource kNotAResource = 0xAAAAA0;
}

TestURLRequest::TestURLRequest(TestingInstance* instance)
    : TestCase(instance),
      ppb_url_request_interface_(NULL),
      ppb_url_loader_interface_(NULL),
      ppb_url_response_interface_(NULL),
      ppb_core_interface_(NULL),
      ppb_var_interface_(NULL) {
}

bool TestURLRequest::Init() {
  ppb_url_request_interface_ = static_cast<const PPB_URLRequestInfo*>(
      pp::Module::Get()->GetBrowserInterface(PPB_URLREQUESTINFO_INTERFACE));
  ppb_url_loader_interface_ = static_cast<const PPB_URLLoader*>(
      pp::Module::Get()->GetBrowserInterface(PPB_URLLOADER_INTERFACE));
  ppb_url_response_interface_ = static_cast<const PPB_URLResponseInfo*>(
      pp::Module::Get()->GetBrowserInterface(PPB_URLRESPONSEINFO_INTERFACE));
  ppb_core_interface_ = static_cast<const PPB_Core*>(
      pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
  ppb_var_interface_ = static_cast<const PPB_Var*>(
      pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
  if (!ppb_url_request_interface_)
    instance_->AppendError("PPB_URLRequestInfo interface not available");
  if (!ppb_url_response_interface_)
    instance_->AppendError("PPB_URLResponseInfo interface not available");
  if (!ppb_core_interface_)
    instance_->AppendError("PPB_Core interface not available");
  if (!ppb_var_interface_)
    instance_->AppendError("PPB_Var interface not available");
  if (!ppb_url_loader_interface_) {
    instance_->AppendError("PPB_URLLoader interface not available");
  }
  return EnsureRunningOverHTTP();
}

void TestURLRequest::RunTests(const std::string& filter) {
  RUN_TEST(CreateAndIsURLRequestInfo, filter);
  RUN_TEST(SetProperty, filter);
  RUN_TEST(AppendDataToBody, filter);
  RUN_TEST(AppendFileToBody, filter);
  RUN_TEST(Stress, filter);
}

PP_Var TestURLRequest::PP_MakeString(const char* s) {
  return ppb_var_interface_->VarFromUtf8(s, static_cast<int32_t>(strlen(s)));
}

// Tests
//   PP_Resource Create(PP_Instance instance)
//   PP_Bool IsURLRequestInfo(PP_Resource resource)
std::string TestURLRequest::TestCreateAndIsURLRequestInfo() {
  // Create: Invalid / non-existent instance -> invalid resource.
  ASSERT_EQ(ppb_url_request_interface_->Create(kInvalidInstance),
            kInvalidResource);
  ASSERT_EQ(ppb_url_request_interface_->Create(kNotAnInstance),
            kInvalidResource);

  // Create: Valid instance -> valid resource.
  PP_Resource url_request = ppb_url_request_interface_->Create(
      instance_->pp_instance());
  ASSERT_NE(url_request, kInvalidResource);

  // IsURLRequestInfo:
  // Invalid / non-existent / non-URLRequestInfo resource -> false.
  ASSERT_NE(PP_TRUE,
            ppb_url_request_interface_->IsURLRequestInfo(kInvalidResource));
  ASSERT_NE(PP_TRUE,
            ppb_url_request_interface_->IsURLRequestInfo(kNotAResource));

  PP_Resource url_loader =
      ppb_url_loader_interface_->Create(instance_->pp_instance());
  ASSERT_NE(kInvalidResource, url_loader);

  ASSERT_NE(PP_TRUE, ppb_url_request_interface_->IsURLRequestInfo(url_loader));
  ppb_url_loader_interface_->Close(url_loader);
  ppb_core_interface_->ReleaseResource(url_loader);

  // IsURLRequestInfo: Current URLRequestInfo resource -> true.
  std::string error;
  if (PP_FALSE == ppb_url_request_interface_->IsURLRequestInfo(url_request))
    error = "IsURLRequestInfo() failed with a current URLRequestInfo resource";

  // IsURLRequestInfo: Released URLRequestInfo resource -> false.
  ppb_core_interface_->ReleaseResource(url_request);
  ASSERT_NE(PP_TRUE, ppb_url_request_interface_->IsURLRequestInfo(url_request));

  return error;  // == PASS() if empty.
}

// Tests
//  PP_Bool SetProperty(PP_Resource request,
//                      PP_URLRequestProperty property,
//                      struct PP_Var value);
std::string TestURLRequest::TestSetProperty() {
  struct PropertyTestData {
    PropertyTestData(PP_URLRequestProperty prop,
                     const std::string& name,
                     PP_Var value, PP_Bool expected) :
        property(prop), property_name(name),
        var(value), expected_value(expected) {
      // var has ref count of 1 on creation.
    }
    PP_URLRequestProperty property;
    std::string property_name;
    PP_Var var;  // Instance owner is responsible for releasing this var.
    PP_Bool expected_value;
  };

  // All bool properties should accept PP_TRUE and PP_FALSE, while rejecting
  // all other variable types.
#define TEST_BOOL(_name)                                              \
    PropertyTestData(ID_STR(_name), PP_MakeBool(PP_TRUE), PP_TRUE),   \
    PropertyTestData(ID_STR(_name), PP_MakeBool(PP_FALSE), PP_TRUE),  \
    PropertyTestData(ID_STR(_name), PP_MakeUndefined(), PP_FALSE),    \
    PropertyTestData(ID_STR(_name), PP_MakeNull(), PP_FALSE),         \
    PropertyTestData(ID_STR(_name), PP_MakeInt32(0), PP_FALSE),       \
    PropertyTestData(ID_STR(_name), PP_MakeDouble(0.0), PP_FALSE)

  // These property types are always invalid for string properties.
#define TEST_STRING_INVALID(_name)                                    \
    PropertyTestData(ID_STR(_name), PP_MakeNull(), PP_FALSE),         \
    PropertyTestData(ID_STR(_name), PP_MakeBool(PP_FALSE), PP_FALSE), \
    PropertyTestData(ID_STR(_name), PP_MakeInt32(0), PP_FALSE),       \
    PropertyTestData(ID_STR(_name), PP_MakeDouble(0.0), PP_FALSE)

#define TEST_INT_INVALID(_name)                                         \
    PropertyTestData(ID_STR(_name), PP_MakeUndefined(), PP_FALSE),      \
    PropertyTestData(ID_STR(_name), PP_MakeNull(), PP_FALSE),           \
    PropertyTestData(ID_STR(_name), PP_MakeBool(PP_FALSE), PP_FALSE),   \
    PropertyTestData(ID_STR(_name), PP_MakeString("notint"), PP_FALSE), \
    PropertyTestData(ID_STR(_name), PP_MakeDouble(0.0), PP_FALSE)

  // SetProperty accepts plenty of invalid values (malformed urls, negative
  // thresholds, etc). Error checking is delayed until request opening (aka url
  // loading).
#define ID_STR(arg) arg, #arg
    PropertyTestData test_data[] = {
      TEST_BOOL(PP_URLREQUESTPROPERTY_STREAMTOFILE),
      TEST_BOOL(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS),
      TEST_BOOL(PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS),
      TEST_BOOL(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS),
      TEST_BOOL(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS),
      TEST_BOOL(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS),
      TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_URL),
      TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_METHOD),
      TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_HEADERS),
      TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
      TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
      TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
      TEST_INT_INVALID(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
      TEST_INT_INVALID(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
                       PP_MakeString("http://www.google.com"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
                       PP_MakeString("foo.jpg"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
                       PP_MakeString("GET"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
                       PP_MakeString("POST"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
                       PP_MakeString("Accept: text/plain"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
                       PP_MakeString(""), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
                       PP_MakeString("http://www.google.com"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
                       PP_MakeString(""), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
                       PP_MakeUndefined(), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
          PP_MakeString("base64"), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
          PP_MakeString(""), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
          PP_MakeUndefined(), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
          PP_MakeString("My Crazy Plugin"), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
          PP_MakeString(""), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
          PP_MakeUndefined(), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
                       PP_MakeUndefined(), PP_FALSE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
                       PP_MakeUndefined(), PP_FALSE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
          PP_MakeString("Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA=="),
          PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
          PP_MakeString("Accept-Encoding: *\n"
                        "Accept-Charset: iso-8859-5, unicode-1-1;q=0.8"),
          PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
          PP_MakeInt32(0), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
          PP_MakeInt32(100), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
          PP_MakeInt32(0), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
          PP_MakeInt32(100), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
                       PP_MakeString("::::::::::::"), PP_TRUE),
      PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
          PP_MakeString("INVALID"), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
          PP_MakeString("invalid"), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
          PP_MakeInt32(-100), PP_TRUE),
      PropertyTestData(
          ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
          PP_MakeInt32(-100), PP_TRUE),

    };
  std::string error;

  PP_Resource url_request = ppb_url_request_interface_->Create(
      instance_->pp_instance());
  if (url_request == kInvalidResource)
    error = "Failed to create a URLRequestInfo";

  // Loop over all test data even if we encountered an error to release vars.
  for (size_t i = 0;
       i < sizeof(test_data) / sizeof(test_data[0]);
       ++i) {
    if (error.empty() && test_data[i].expected_value !=
        ppb_url_request_interface_->SetProperty(url_request,
                                                test_data[i].property,
                                                test_data[i].var)) {
      pp::Var var(pp::Var::DontManage(), test_data[i].var);
      error = std::string("Setting property ") +
          test_data[i].property_name + " to " + var.DebugString() +
          " did not return " + (test_data[i].expected_value ? "True" : "False");
      error = test_data[i].property_name;
    }
    ppb_var_interface_->Release(test_data[i].var);
  }

  ppb_core_interface_->ReleaseResource(url_request);
  return error;  // == PASS() if empty.
}

std::string TestURLRequest::LoadAndCompareBody(
    PP_Resource url_request, const std::string& expected_body) {
  TestCompletionCallback callback(instance_->pp_instance(), PP_REQUIRED);

  PP_Resource url_loader =
      ppb_url_loader_interface_->Create(instance_->pp_instance());
  ASSERT_NE(kInvalidResource, url_loader);

  callback.WaitForResult(ppb_url_loader_interface_->Open(
      url_loader, url_request,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  std::string error;
  PP_Resource url_response =
      ppb_url_loader_interface_->GetResponseInfo(url_loader);
  if (url_response == kInvalidResource) {
    error = "PPB_URLLoader::GetResponseInfo() returned invalid resource";
  } else {
    PP_Var status = ppb_url_response_interface_->GetProperty(
        url_response, PP_URLRESPONSEPROPERTY_STATUSCODE);
    if (status.type != PP_VARTYPE_INT32 && status.value.as_int != 200)
      error = ReportError("PPB_URLLoader::Open() status", status.value.as_int);

    std::string actual_body;
    for (; error.empty();) {  // Read the entire body in this loop.
      const size_t kBufferSize = 32;
      char buf[kBufferSize];
      callback.WaitForResult(ppb_url_loader_interface_->ReadResponseBody(
          url_loader, buf, kBufferSize,
          callback.GetCallback().pp_completion_callback()));
      if (callback.failed())
        error.assign(callback.errors());
      else if (callback.result() < PP_OK)
        error.assign(ReportError("PPB_URLLoader::ReadResponseBody()",
                                 callback.result()));
      if (callback.result() <= PP_OK || callback.failed())
        break;
      actual_body.append(buf, callback.result());
    }
    if (actual_body != expected_body)
      error = "PPB_URLLoader::ReadResponseBody() read unexpected response.";
  }
  ppb_core_interface_->ReleaseResource(url_response);

  ppb_url_loader_interface_->Close(url_loader);
  ppb_core_interface_->ReleaseResource(url_loader);
  return error;
}

// Tests
//   PP_Bool AppendDataToBody(
//       PP_Resource request, const void* data, uint32_t len);
std::string TestURLRequest::TestAppendDataToBody() {
  PP_Resource url_request = ppb_url_request_interface_->Create(
      instance_->pp_instance());
  ASSERT_NE(url_request, kInvalidResource);

  std::string postdata("sample postdata");
  PP_Var post_string_var = PP_MakeString("POST");
  PP_Var echo_string_var = PP_MakeString("/echo");

  // NULL pointer causes a crash. In general PPAPI implementation does not
  // test for NULL because they are just a special case of bad pointers that
  // are not detectable if set to point to an object that does not exist.

  // Invalid resource should fail.
  ASSERT_EQ(PP_FALSE, ppb_url_request_interface_->AppendDataToBody(
      kInvalidResource, postdata.data(),
      static_cast<uint32_t>(postdata.length())));

  // Append data and POST to echoing web server.
  ASSERT_EQ(PP_TRUE, ppb_url_request_interface_->SetProperty(
      url_request, PP_URLREQUESTPROPERTY_METHOD, post_string_var));
  ASSERT_EQ(PP_TRUE, ppb_url_request_interface_->SetProperty(
      url_request, PP_URLREQUESTPROPERTY_URL, echo_string_var));

  // Append data to body and verify the body is what we expect.
  ASSERT_EQ(PP_TRUE, ppb_url_request_interface_->AppendDataToBody(
      url_request, postdata.data(),
      static_cast<uint32_t>(postdata.length())));
  std::string error = LoadAndCompareBody(url_request, postdata);

  ppb_var_interface_->Release(post_string_var);
  ppb_var_interface_->Release(echo_string_var);
  ppb_core_interface_->ReleaseResource(url_request);
  return error;  // == PASS() if empty.
}

std::string TestURLRequest::TestAppendFileToBody() {
  PP_Resource url_request = ppb_url_request_interface_->Create(
      instance_->pp_instance());
  ASSERT_NE(url_request, kInvalidResource);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef ref(file_system, "/test_file");
  pp::FileIO io(instance_);
  callback.WaitForResult(io.Open(ref,
                                 PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE,
                                 callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  std::string append_data = "hello\n";
  callback.WaitForResult(io.Write(0,
                                  append_data.c_str(),
                                  static_cast<int32_t>(append_data.size()),
                                  callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(static_cast<int32_t>(append_data.size()), callback.result());

  PP_Var post_string_var = PP_MakeString("POST");
  PP_Var echo_string_var = PP_MakeString("/echo");

  // NULL pointer causes a crash. In general PPAPI implementation does not
  // test for NULL because they are just a special case of bad pointers that
  // are not detectable if set to point to an object that does not exist.

  // Invalid resource should fail.
  ASSERT_EQ(PP_FALSE, ppb_url_request_interface_->AppendFileToBody(
      kInvalidResource, ref.pp_resource(), 0, -1, 0));

  // Append data and POST to echoing web server.
  ASSERT_EQ(PP_TRUE, ppb_url_request_interface_->SetProperty(
      url_request, PP_URLREQUESTPROPERTY_METHOD, post_string_var));
  ASSERT_EQ(PP_TRUE, ppb_url_request_interface_->SetProperty(
      url_request, PP_URLREQUESTPROPERTY_URL, echo_string_var));

  // Append file to body and verify the body is what we expect.
  ASSERT_EQ(PP_TRUE, ppb_url_request_interface_->AppendFileToBody(
      url_request, ref.pp_resource(), 0, -1, 0));
  std::string error = LoadAndCompareBody(url_request, append_data);

  ppb_var_interface_->Release(post_string_var);
  ppb_var_interface_->Release(echo_string_var);
  ppb_core_interface_->ReleaseResource(url_request);
  return error;  // == PASS() if empty.
}

// Allocates and manipulates a large number of resources.
std::string TestURLRequest::TestStress() {
  const int kManyResources = 500;
  PP_Resource url_request_info[kManyResources];

  std::string error;
  int num_created = kManyResources;
  for (int i = 0; i < kManyResources; i++) {
    url_request_info[i] = ppb_url_request_interface_->Create(
        instance_->pp_instance());
    if (url_request_info[i] == kInvalidResource) {
      error = "Create() failed";
    } else if (PP_FALSE == ppb_url_request_interface_->IsURLRequestInfo(
        url_request_info[i])) {
      error = "IsURLRequestInfo() failed";
    } else if (PP_FALSE == ppb_url_request_interface_->SetProperty(
        url_request_info[i],
        PP_URLREQUESTPROPERTY_STREAMTOFILE,
        PP_MakeBool(PP_FALSE))) {
      error = "SetProperty() failed";
    }
    if (!error.empty()) {
      num_created = i + 1;
      break;
    }
  }
  for (int i = 0; i < num_created; i++) {
    ppb_core_interface_->ReleaseResource(url_request_info[i]);
    if (PP_TRUE ==
        ppb_url_request_interface_->IsURLRequestInfo(url_request_info[i]))
      error = "IsURLREquestInfo() succeeded after release";
  }
  return error;  // == PASS() if empty.
}
