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

#if defined(_MSC_VER)
#define OS_WIN 1
#include <windows.h>
#else
#define OS_POSIX 1
#include <errno.h>
#include <unistd.h>
#endif

#include <cstdio>
#include <cstring>
#include <fstream>
#include <limits>

#include "ppapi/c/pp_errors.h"
#include "ppapi/c/trusted/ppp_broker.h"
#include "ppapi/c/trusted/ppb_broker_trusted.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(Broker);

namespace {

const char kHelloMessage[] = "Hello Plugin! This is Broker!";
// Message sent from broker to plugin if the broker is unsandboxed.
const char kBrokerUnsandboxed[] = "Broker is Unsandboxed!";
// Message sent from broker to plugin if the broker is sandboxed. This message
// needs to be longer than |kBrokerUnsandboxed| because the plugin is expecting
// |kBrokerUnsandboxed|. If it's shorter and the broker doesn't close its handle
// properly the plugin will hang waiting for all data of |kBrokerUnsandboxed| to
// be read.
const char kBrokerSandboxed[] = "Broker is Sandboxed! Verification failed!";

#if defined(OS_WIN)
typedef HANDLE PlatformFile;
const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
const int32_t kInvalidHandle = static_cast<int32_t>(
    reinterpret_cast<intptr_t>(INVALID_HANDLE_VALUE));
#elif defined(OS_POSIX)
typedef int PlatformFile;
const PlatformFile kInvalidPlatformFileValue = -1;
const int32_t kInvalidHandle = -1;
#endif

PlatformFile IntToPlatformFile(int32_t handle) {
#if defined(OS_WIN)
  return reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle));
#elif defined(OS_POSIX)
  return handle;
#endif
}

#if defined(OS_POSIX)

#define HANDLE_EINTR(x) ({ \
  typeof(x) eintr_wrapper_result; \
  do { \
    eintr_wrapper_result = (x); \
  } while (eintr_wrapper_result == -1 && errno == EINTR); \
  eintr_wrapper_result; \
})

#define IGNORE_EINTR(x) ({ \
  typeof(x) eintr_wrapper_result; \
  do { \
    eintr_wrapper_result = (x); \
    if (eintr_wrapper_result == -1 && errno == EINTR) { \
      eintr_wrapper_result = 0; \
    } \
  } while (0); \
  eintr_wrapper_result; \
})

#endif

bool ReadMessage(PlatformFile file, size_t message_len, char* message) {
#if defined(OS_WIN)
  assert(message_len < std::numeric_limits<DWORD>::max());
  DWORD read = 0;
  const DWORD size = static_cast<DWORD>(message_len);
  return ::ReadFile(file, message, size, &read, NULL) && read == size;
#elif defined(OS_POSIX)
  assert(message_len <
         static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  size_t total_read = 0;
  while (total_read < message_len) {
    ssize_t read = HANDLE_EINTR(::read(file, message + total_read,
                                       message_len - total_read));
    if (read <= 0)
      break;
    total_read += read;
  }
  return total_read == message_len;
#endif
}

bool WriteMessage(PlatformFile file, size_t message_len, const char* message) {
#if defined(OS_WIN)
  assert(message_len < std::numeric_limits<DWORD>::max());
  DWORD written = 0;
  const DWORD size = static_cast<DWORD>(message_len);
  return ::WriteFile(file, message, size, &written, NULL) && written == size;
#elif defined(OS_POSIX)
  assert(message_len <
         static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  size_t total_written = 0;
  while (total_written < message_len) {
    ssize_t written = HANDLE_EINTR(::write(file, message + total_written,
                                           message_len - total_written));
    if (written <= 0)
      break;
    total_written += written;
  }
  return total_written == message_len;
#endif
}

bool VerifyMessage(PlatformFile file, size_t message_len, const char* message) {
  char* message_received = new char[message_len];
  bool success = ReadMessage(file, message_len, message_received) &&
                 !::strcmp(message_received, message);
  delete [] message_received;
  return success;
}

bool ClosePlatformFile(PlatformFile file) {
#if defined(OS_WIN)
  return !!::CloseHandle(file);
#elif defined(OS_POSIX)
  return !IGNORE_EINTR(::close(file));
#endif
}

bool VerifyIsUnsandboxed() {
#if defined(OS_WIN)
  FILE* file = NULL;
  wchar_t temp_path[MAX_PATH] = {'\0'};
  wchar_t file_name[MAX_PATH] = {'\0'};
  if (!::GetTempPath(MAX_PATH, temp_path) ||
      !::GetTempFileName(temp_path, L"test_pepper_broker", 0, file_name) ||
      ::_wfopen_s(&file, file_name, L"w"))
    return false;

  if (::fclose(file)) {
    ::DeleteFile(file_name);
    return false;
  }

  return !!::DeleteFile(file_name);
#elif defined(OS_POSIX)
  char file_name[] = "/tmp/test_pepper_broker_XXXXXX";
  int fd = ::mkstemp(file_name);
  if (-1 == fd)
    return false;

  if (IGNORE_EINTR(::close(fd))) {
    ::remove(file_name);
    return false;
  }

  return !::remove(file_name);
#endif
}

// Callback in the broker when a new broker connection occurs.
int32_t OnInstanceConnected(PP_Instance instance, int32_t handle) {
  PlatformFile file = IntToPlatformFile(handle);
  if (file == kInvalidPlatformFileValue)
    return PP_ERROR_FAILED;

  // Send hello message.
  if (!WriteMessage(file, sizeof(kHelloMessage), kHelloMessage)) {
    ClosePlatformFile(file);
    return PP_ERROR_FAILED;
  }

  // Verify broker is not sandboxed and send result to plugin over the pipe.
  if (VerifyIsUnsandboxed()) {
    if (!WriteMessage(file, sizeof(kBrokerUnsandboxed), kBrokerUnsandboxed)) {
      ClosePlatformFile(file);
      return PP_ERROR_FAILED;
    }
  } else {
    if (!WriteMessage(file, sizeof(kBrokerSandboxed), kBrokerSandboxed)) {
      ClosePlatformFile(file);
      return PP_ERROR_FAILED;
    }
  }

  if (!ClosePlatformFile(file))
    return PP_ERROR_FAILED;

  return PP_OK;
}

}  // namespace

PP_EXPORT int32_t PPP_InitializeBroker(
    PP_ConnectInstance_Func* connect_instance_func) {
  *connect_instance_func = &OnInstanceConnected;
  return PP_OK;
}

PP_EXPORT void PPP_ShutdownBroker() {}

TestBroker::TestBroker(TestingInstance* instance)
    : TestCase(instance),
      broker_interface_(NULL) {
}

bool TestBroker::Init() {
  broker_interface_ = static_cast<const PPB_BrokerTrusted*>(
      pp::Module::Get()->GetBrowserInterface(PPB_BROKER_TRUSTED_INTERFACE));
  return !!broker_interface_;
}

void TestBroker::RunTests(const std::string& filter) {
  RUN_TEST(Create, filter);
  RUN_TEST(Create, filter);
  RUN_TEST(GetHandleFailure, filter);
  RUN_TEST_FORCEASYNC_AND_NOT(ConnectFailure, filter);
  RUN_TEST_FORCEASYNC_AND_NOT(ConnectAndPipe, filter);

  // The following tests require special setup, so only run them if they're
  // explicitly specified by the filter.
  if (!ShouldRunAllTests(filter)) {
    RUN_TEST(ConnectPermissionDenied, filter);
    RUN_TEST(ConnectPermissionGranted, filter);
    RUN_TEST(IsAllowedPermissionDenied, filter);
    RUN_TEST(IsAllowedPermissionGranted, filter);
  }
}

std::string TestBroker::TestCreate() {
  // Very simplistic test to make sure we can create a broker interface.
  // TODO(raymes): All of the resources created in this file are leaked. Write
  // a C++ wrapper for PPB_Broker_Trusted to avoid these leaks.
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);

  ASSERT_FALSE(broker_interface_->IsBrokerTrusted(0));
  ASSERT_TRUE(broker_interface_->IsBrokerTrusted(broker));

  PASS();
}

// Test connection on invalid resource.
std::string TestBroker::TestConnectFailure() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(broker_interface_->Connect(0,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_BADRESOURCE, callback.result());

  PASS();
}

std::string TestBroker::TestGetHandleFailure() {
  int32_t handle = kInvalidHandle;

  // Test getting the handle for an invalid resource.
  ASSERT_EQ(PP_ERROR_BADRESOURCE, broker_interface_->GetHandle(0, &handle));

  // Connect hasn't been called so this should fail.
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);
  ASSERT_EQ(PP_ERROR_FAILED, broker_interface_->GetHandle(broker, &handle));

  PASS();
}

std::string TestBroker::TestConnectAndPipe() {
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(broker_interface_->Connect(broker,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  int32_t handle = kInvalidHandle;
  ASSERT_EQ(PP_OK, broker_interface_->GetHandle(broker, &handle));
  ASSERT_NE(kInvalidHandle, handle);

  PlatformFile file = IntToPlatformFile(handle);
  ASSERT_TRUE(VerifyMessage(file, sizeof(kHelloMessage), kHelloMessage));
  ASSERT_TRUE(VerifyMessage(file, sizeof(kBrokerUnsandboxed),
                            kBrokerUnsandboxed));

  ASSERT_TRUE(ClosePlatformFile(file));

  PASS();
}

std::string TestBroker::TestConnectPermissionDenied() {
  // This assumes that the browser side is set up to deny access to the broker.
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(broker_interface_->Connect(broker,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_NOACCESS, callback.result());

  PASS();
}

std::string TestBroker::TestConnectPermissionGranted() {
  // This assumes that the browser side is set up to allow access to the broker.
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  callback.WaitForResult(broker_interface_->Connect(broker,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  PASS();
}

std::string TestBroker::TestIsAllowedPermissionDenied() {
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);
  ASSERT_EQ(PP_FALSE, broker_interface_->IsAllowed(broker));

  PASS();
}

std::string TestBroker::TestIsAllowedPermissionGranted() {
  PP_Resource broker = broker_interface_->CreateTrusted(
      instance_->pp_instance());
  ASSERT_TRUE(broker);
  ASSERT_EQ(PP_TRUE, broker_interface_->IsAllowed(broker));

  PASS();
}
