// Copyright 2016 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 "mojo/core/test/mojo_test_base.h"

#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "build/build_config.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/c/system/buffer.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/functions.h"
#include "mojo/public/c/system/trap.h"
#include "mojo/public/cpp/system/handle.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/cpp/system/wait.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace core {
namespace test {

MojoTestBase::MojoTestBase() = default;

MojoTestBase::~MojoTestBase() = default;

MojoTestBase::ClientController& MojoTestBase::StartClient(
    const std::string& client_name) {
  clients_.push_back(
      std::make_unique<ClientController>(client_name, this, launch_type_));
  return *clients_.back();
}

MojoTestBase::ClientController::ClientController(const std::string& client_name,
                                                 MojoTestBase* test,
                                                 LaunchType launch_type) {
#if !defined(OS_IOS)
  pipe_ = helper_.StartChild(client_name, launch_type);
#endif
}

MojoTestBase::ClientController::~ClientController() {
  CHECK(was_shutdown_)
      << "Test clients should be waited on explicitly with WaitForShutdown().";
}

int MojoTestBase::ClientController::WaitForShutdown() {
  was_shutdown_ = true;
#if !defined(OS_IOS)
  int retval = helper_.WaitForChildShutdown();
  return retval;
#else
  NOTREACHED();
  return 1;
#endif
}

// static
void MojoTestBase::CloseHandle(MojoHandle h) {
  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h));
}

// static
void MojoTestBase::CreateMessagePipe(MojoHandle* p0, MojoHandle* p1) {
  MojoCreateMessagePipe(nullptr, p0, p1);
  CHECK_NE(*p0, MOJO_HANDLE_INVALID);
  CHECK_NE(*p1, MOJO_HANDLE_INVALID);
}

// static
void MojoTestBase::WriteMessageWithHandles(MojoHandle mp,
                                           const std::string& message,
                                           const MojoHandle* handles,
                                           uint32_t num_handles) {
  CHECK_EQ(WriteMessageRaw(MessagePipeHandle(mp), message.data(),
                           static_cast<uint32_t>(message.size()), handles,
                           num_handles, MOJO_WRITE_MESSAGE_FLAG_NONE),
           MOJO_RESULT_OK);
}

// static
void MojoTestBase::WriteMessage(MojoHandle mp, const std::string& message) {
  WriteMessageWithHandles(mp, message, nullptr, 0);
}

// static
std::string MojoTestBase::ReadMessageWithHandles(
    MojoHandle mp,
    MojoHandle* out_handles,
    uint32_t expected_num_handles) {
  CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);

  std::vector<uint8_t> bytes;
  std::vector<ScopedHandle> handles;
  CHECK_EQ(MOJO_RESULT_OK,
           ReadMessageRaw(MessagePipeHandle(mp), &bytes, &handles,
                          MOJO_READ_MESSAGE_FLAG_NONE));
  CHECK_EQ(expected_num_handles, handles.size());
  for (size_t i = 0; i < handles.size(); ++i)
    out_handles[i] = handles[i].release().value();

  return std::string(bytes.begin(), bytes.end());
}

// static
std::string MojoTestBase::ReadMessageWithOptionalHandle(MojoHandle mp,
                                                        MojoHandle* handle) {
  CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);

  std::vector<uint8_t> bytes;
  std::vector<ScopedHandle> handles;
  CHECK_EQ(MOJO_RESULT_OK,
           ReadMessageRaw(MessagePipeHandle(mp), &bytes, &handles,
                          MOJO_READ_MESSAGE_FLAG_NONE));
  CHECK(handles.size() == 0 || handles.size() == 1);
  CHECK(handle);

  if (handles.size() == 1)
    *handle = handles[0].release().value();
  else
    *handle = MOJO_HANDLE_INVALID;

  return std::string(bytes.begin(), bytes.end());
}

// static
std::string MojoTestBase::ReadMessage(MojoHandle mp) {
  return ReadMessageWithHandles(mp, nullptr, 0);
}

// static
void MojoTestBase::ReadMessage(MojoHandle mp, char* data, size_t num_bytes) {
  CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);

  std::vector<uint8_t> bytes;
  std::vector<ScopedHandle> handles;
  CHECK_EQ(MOJO_RESULT_OK,
           ReadMessageRaw(MessagePipeHandle(mp), &bytes, &handles,
                          MOJO_READ_MESSAGE_FLAG_NONE));
  CHECK_EQ(0u, handles.size());
  CHECK_EQ(num_bytes, bytes.size());
  memcpy(data, bytes.data(), bytes.size());
}

// static
void MojoTestBase::VerifyTransmission(MojoHandle source,
                                      MojoHandle dest,
                                      const std::string& message) {
  WriteMessage(source, message);

  // We don't use EXPECT_EQ; failures on really long messages make life hard.
  EXPECT_TRUE(message == ReadMessage(dest));
}

// static
void MojoTestBase::VerifyEcho(MojoHandle mp, const std::string& message) {
  VerifyTransmission(mp, mp, message);
}

// static
MojoHandle MojoTestBase::CreateBuffer(uint64_t size) {
  MojoHandle h;
  EXPECT_EQ(MojoCreateSharedBuffer(size, nullptr, &h), MOJO_RESULT_OK);
  return h;
}

// static
MojoHandle MojoTestBase::DuplicateBuffer(MojoHandle h, bool read_only) {
  MojoHandle new_handle;
  MojoDuplicateBufferHandleOptions options = {
      sizeof(MojoDuplicateBufferHandleOptions),
      MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_NONE};
  if (read_only)
    options.flags |= MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY;
  EXPECT_EQ(MOJO_RESULT_OK,
            MojoDuplicateBufferHandle(h, &options, &new_handle));
  return new_handle;
}

// static
void MojoTestBase::WriteToBuffer(MojoHandle h,
                                 size_t offset,
                                 const base::StringPiece& s) {
  char* data;
  EXPECT_EQ(MOJO_RESULT_OK, MojoMapBuffer(h, offset, s.size(), nullptr,
                                          reinterpret_cast<void**>(&data)));
  memcpy(data, s.data(), s.size());
  EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(static_cast<void*>(data)));
}

// static
void MojoTestBase::ExpectBufferContents(MojoHandle h,
                                        size_t offset,
                                        const base::StringPiece& s) {
  char* data;
  EXPECT_EQ(MOJO_RESULT_OK, MojoMapBuffer(h, offset, s.size(), nullptr,
                                          reinterpret_cast<void**>(&data)));
  EXPECT_EQ(s, base::StringPiece(data, s.size()));
  EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(static_cast<void*>(data)));
}

// static
void MojoTestBase::CreateDataPipe(MojoHandle* p0,
                                  MojoHandle* p1,
                                  size_t capacity) {
  MojoCreateDataPipeOptions options;
  options.struct_size = static_cast<uint32_t>(sizeof(options));
  options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
  options.element_num_bytes = 1;
  options.capacity_num_bytes = static_cast<uint32_t>(capacity);

  MojoCreateDataPipe(&options, p0, p1);
  CHECK_NE(*p0, MOJO_HANDLE_INVALID);
  CHECK_NE(*p1, MOJO_HANDLE_INVALID);
}

// static
void MojoTestBase::WriteData(MojoHandle producer, const std::string& data) {
  CHECK_EQ(WaitForSignals(producer, MOJO_HANDLE_SIGNAL_WRITABLE),
           MOJO_RESULT_OK);
  uint32_t num_bytes = static_cast<uint32_t>(data.size());
  MojoWriteDataOptions options;
  options.struct_size = sizeof(options);
  options.flags = MOJO_WRITE_DATA_FLAG_ALL_OR_NONE;
  CHECK_EQ(MojoWriteData(producer, data.data(), &num_bytes, &options),
           MOJO_RESULT_OK);
  CHECK_EQ(num_bytes, static_cast<uint32_t>(data.size()));
}

// static
std::string MojoTestBase::ReadData(MojoHandle consumer, size_t size) {
  CHECK_EQ(WaitForSignals(consumer, MOJO_HANDLE_SIGNAL_READABLE),
           MOJO_RESULT_OK);
  std::vector<char> buffer(size);
  uint32_t num_bytes = static_cast<uint32_t>(size);
  MojoReadDataOptions options;
  options.struct_size = sizeof(options);
  options.flags = MOJO_READ_DATA_FLAG_ALL_OR_NONE;
  CHECK_EQ(MojoReadData(consumer, &options, buffer.data(), &num_bytes),
           MOJO_RESULT_OK);
  CHECK_EQ(num_bytes, static_cast<uint32_t>(size));

  return std::string(buffer.begin(), buffer.end());
}

// static
MojoHandleSignalsState MojoTestBase::GetSignalsState(MojoHandle handle) {
  MojoHandleSignalsState signals_state;
  CHECK_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(handle, &signals_state));
  return signals_state;
}

// static
MojoResult MojoTestBase::WaitForSignals(MojoHandle handle,
                                        MojoHandleSignals signals,
                                        MojoTriggerCondition condition,
                                        MojoHandleSignalsState* state) {
  return Wait(Handle(handle), signals, condition, state);
}

// static
MojoResult MojoTestBase::WaitForSignals(MojoHandle handle,
                                        MojoHandleSignals signals,
                                        MojoHandleSignalsState* state) {
  return Wait(Handle(handle), signals, MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
              state);
}

}  // namespace test
}  // namespace core
}  // namespace mojo
