// Copyright 2014 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/edk/system/shared_buffer_dispatcher.h"

#include <limits>
#include <memory>

#include "mojo/edk/embedder/simple_platform_support.h"
#include "mojo/edk/platform/platform_shared_buffer.h"
#include "mojo/edk/system/dispatcher.h"
#include "mojo/public/cpp/system/macros.h"
#include "testing/gtest/include/gtest/gtest.h"

using mojo::platform::PlatformSharedBufferMapping;
using mojo::util::RefPtr;

namespace mojo {
namespace system {
namespace {

// NOTE(vtl): There's currently not much to test for in
// |SharedBufferDispatcher::ValidateCreateOptions()|, but the tests should be
// expanded if/when options are added, so I've kept the general form of the
// tests from data_pipe_unittest.cc.

const uint32_t kSizeOfCreateOptions = sizeof(MojoCreateSharedBufferOptions);

// Does a cursory sanity check of |validated_options|. Calls
// |ValidateCreateOptions()| on already-validated options. The validated options
// should be valid, and the revalidated copy should be the same.
void RevalidateCreateOptions(
    const MojoCreateSharedBufferOptions& validated_options) {
  EXPECT_EQ(kSizeOfCreateOptions, validated_options.struct_size);
  // Nothing to check for flags.

  MojoCreateSharedBufferOptions revalidated_options = {};
  EXPECT_EQ(MOJO_RESULT_OK,
            SharedBufferDispatcher::ValidateCreateOptions(
                MakeUserPointer(&validated_options), &revalidated_options));
  EXPECT_EQ(validated_options.struct_size, revalidated_options.struct_size);
  EXPECT_EQ(validated_options.flags, revalidated_options.flags);
}

class SharedBufferDispatcherTest : public testing::Test {
 public:
  SharedBufferDispatcherTest()
      : platform_support_(embedder::CreateSimplePlatformSupport()) {}
  ~SharedBufferDispatcherTest() override {}

  embedder::PlatformSupport* platform_support() {
    return platform_support_.get();
  }

 private:
  std::unique_ptr<embedder::PlatformSupport> platform_support_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(SharedBufferDispatcherTest);
};

// Tests valid inputs to |ValidateCreateOptions()|.
TEST_F(SharedBufferDispatcherTest, ValidateCreateOptionsValid) {
  // Default options.
  {
    MojoCreateSharedBufferOptions validated_options = {};
    EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::ValidateCreateOptions(
                                  NullUserPointer(), &validated_options));
    RevalidateCreateOptions(validated_options);
  }

  // Different flags.
  MojoCreateSharedBufferOptionsFlags flags_values[] = {
      MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE};
  for (size_t i = 0; i < MOJO_ARRAYSIZE(flags_values); i++) {
    const MojoCreateSharedBufferOptionsFlags flags = flags_values[i];

    // Different capacities (size 1).
    for (uint32_t capacity = 1; capacity <= 100 * 1000 * 1000; capacity *= 10) {
      MojoCreateSharedBufferOptions options = {
          kSizeOfCreateOptions,  // |struct_size|.
          flags                  // |flags|.
      };
      MojoCreateSharedBufferOptions validated_options = {};
      EXPECT_EQ(MOJO_RESULT_OK,
                SharedBufferDispatcher::ValidateCreateOptions(
                    MakeUserPointer(&options), &validated_options))
          << capacity;
      RevalidateCreateOptions(validated_options);
      EXPECT_EQ(options.flags, validated_options.flags);
    }
  }
}

TEST_F(SharedBufferDispatcherTest, ValidateCreateOptionsInvalid) {
  // Invalid |struct_size|.
  {
    MojoCreateSharedBufferOptions options = {
        1,                                           // |struct_size|.
        MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE  // |flags|.
    };
    MojoCreateSharedBufferOptions unused;
    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
              SharedBufferDispatcher::ValidateCreateOptions(
                  MakeUserPointer(&options), &unused));
  }

  // Unknown |flags|.
  {
    MojoCreateSharedBufferOptions options = {
        kSizeOfCreateOptions,  // |struct_size|.
        ~0u                    // |flags|.
    };
    MojoCreateSharedBufferOptions unused;
    EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
              SharedBufferDispatcher::ValidateCreateOptions(
                  MakeUserPointer(&options), &unused));
  }
}

TEST_F(SharedBufferDispatcherTest, CreateAndMapBuffer) {
  const uint64_t kSize = 100u;

  MojoResult result = MOJO_RESULT_INTERNAL;
  auto dispatcher = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, kSize,
      &result);
  EXPECT_EQ(MOJO_RESULT_OK, result);

  ASSERT_TRUE(dispatcher);
  EXPECT_EQ(Dispatcher::Type::SHARED_BUFFER, dispatcher->GetType());

  // Get information about the buffer (in particular the size) and check it.
  MojoBufferInformation info = {};
  EXPECT_EQ(MOJO_RESULT_OK,
            dispatcher->GetBufferInformation(
                MakeUserPointer(&info), static_cast<uint32_t>(sizeof(info))));
  EXPECT_EQ(sizeof(MojoBufferInformation), info.struct_size);
  EXPECT_EQ(MOJO_BUFFER_INFORMATION_FLAG_NONE, info.flags);
  EXPECT_EQ(kSize, info.num_bytes);

  // Also check that some invalid calls to |GetBufferInformation()| fail in the
  // expected way.
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher->GetBufferInformation(MakeUserPointer(&info), 0u));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher->GetBufferInformation(MakeUserPointer(&info), 15u));

  // It's also valid to call it with a larger-than-required |info_num_bytes|.
  // (Note: The pointer must be aligned, so we use an array of two
  // |MojoBufferInformation|s.)
  MojoBufferInformation infos[2] = {};
  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->GetBufferInformation(
                                MakeUserPointer(&infos[0]),
                                static_cast<uint32_t>(sizeof(infos[0]) + 1)));
  EXPECT_EQ(kSize, infos[0].num_bytes);

  // Make a couple of mappings.
  std::unique_ptr<PlatformSharedBufferMapping> mapping1;
  EXPECT_EQ(
      MOJO_RESULT_OK,
      dispatcher->MapBuffer(0u, kSize, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
  ASSERT_TRUE(mapping1);
  ASSERT_TRUE(mapping1->GetBase());
  EXPECT_EQ(kSize, mapping1->GetLength());
  // Write something.
  static_cast<char*>(mapping1->GetBase())[50] = 'x';

  std::unique_ptr<PlatformSharedBufferMapping> mapping2;
  EXPECT_EQ(MOJO_RESULT_OK,
            dispatcher->MapBuffer(kSize / 2, kSize / 2,
                                  MOJO_MAP_BUFFER_FLAG_NONE, &mapping2));
  ASSERT_TRUE(mapping2);
  ASSERT_TRUE(mapping2->GetBase());
  EXPECT_EQ(kSize / 2, mapping2->GetLength());
  EXPECT_EQ('x', static_cast<char*>(mapping2->GetBase())[0]);

  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());

  // Check that we can still read/write to mappings after the dispatcher has
  // gone away.
  static_cast<char*>(mapping2->GetBase())[1] = 'y';
  EXPECT_EQ('y', static_cast<char*>(mapping1->GetBase())[kSize / 2 + 1]);
}

TEST_F(SharedBufferDispatcherTest, SupportsEntrypointClass) {
  MojoResult result = MOJO_RESULT_INTERNAL;
  auto d = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, 100u,
      &result);
  ASSERT_TRUE(d);
  EXPECT_EQ(MOJO_RESULT_OK, result);

  EXPECT_FALSE(
      d->SupportsEntrypointClass(Dispatcher::EntrypointClass::MESSAGE_PIPE));
  EXPECT_FALSE(d->SupportsEntrypointClass(
      Dispatcher::EntrypointClass::DATA_PIPE_PRODUCER));
  EXPECT_FALSE(d->SupportsEntrypointClass(
      Dispatcher::EntrypointClass::DATA_PIPE_CONSUMER));
  EXPECT_TRUE(d->SupportsEntrypointClass(Dispatcher::EntrypointClass::BUFFER));

  // TODO(vtl): Check that it actually returns |MOJO_RESULT_INVALID_ARGUMENT|
  // for methods in unsupported entrypoint classes.

  EXPECT_EQ(MOJO_RESULT_OK, d->Close());
}

TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandle) {
  const uint64_t kSize = 100u;

  MojoResult result = MOJO_RESULT_INTERNAL;
  auto dispatcher1 = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, kSize,
      &result);
  EXPECT_EQ(MOJO_RESULT_OK, result);

  // Map and write something.
  std::unique_ptr<PlatformSharedBufferMapping> mapping;
  EXPECT_EQ(
      MOJO_RESULT_OK,
      dispatcher1->MapBuffer(0u, kSize, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
  static_cast<char*>(mapping->GetBase())[0] = 'x';
  mapping.reset();

  // Duplicate |dispatcher1| and then close it.
  RefPtr<Dispatcher> dispatcher2;
  EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->DuplicateBufferHandle(
                                NullUserPointer(), &dispatcher2));
  ASSERT_TRUE(dispatcher2);
  EXPECT_EQ(Dispatcher::Type::SHARED_BUFFER, dispatcher2->GetType());

  EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());

  // Make sure that |dispatcher2| still reports the right information.
  MojoBufferInformation info = {};
  EXPECT_EQ(MOJO_RESULT_OK,
            dispatcher2->GetBufferInformation(
                MakeUserPointer(&info), static_cast<uint32_t>(sizeof(info))));
  EXPECT_EQ(sizeof(MojoBufferInformation), info.struct_size);
  EXPECT_EQ(MOJO_BUFFER_INFORMATION_FLAG_NONE, info.flags);
  EXPECT_EQ(kSize, info.num_bytes);

  // Map |dispatcher2| and read something.
  EXPECT_EQ(
      MOJO_RESULT_OK,
      dispatcher2->MapBuffer(0u, kSize, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
  EXPECT_EQ('x', static_cast<char*>(mapping->GetBase())[0]);

  EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
}

TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsValid) {
  MojoResult result = MOJO_RESULT_INTERNAL;
  auto dispatcher1 = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, 100,
      &result);
  EXPECT_EQ(MOJO_RESULT_OK, result);

  MojoDuplicateBufferHandleOptions options[] = {
      {sizeof(MojoDuplicateBufferHandleOptions),
       MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE},
      {sizeof(MojoDuplicateBufferHandleOptionsFlags), ~0u}};
  for (size_t i = 0; i < MOJO_ARRAYSIZE(options); i++) {
    RefPtr<Dispatcher> dispatcher2;
    EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->DuplicateBufferHandle(
                                  MakeUserPointer(&options[i]), &dispatcher2));
    ASSERT_TRUE(dispatcher2);
    EXPECT_EQ(Dispatcher::Type::SHARED_BUFFER, dispatcher2->GetType());
    EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
  }

  EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
}

TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsInvalid) {
  MojoResult result = MOJO_RESULT_INTERNAL;
  auto dispatcher1 = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, 100,
      &result);
  EXPECT_EQ(MOJO_RESULT_OK, result);

  // Invalid |struct_size|.
  {
    MojoDuplicateBufferHandleOptions options = {
        1u, MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE};
    RefPtr<Dispatcher> dispatcher2;
    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
              dispatcher1->DuplicateBufferHandle(MakeUserPointer(&options),
                                                 &dispatcher2));
    EXPECT_FALSE(dispatcher2);
  }

  // Unknown |flags|.
  {
    MojoDuplicateBufferHandleOptions options = {
        sizeof(MojoDuplicateBufferHandleOptions), ~0u};
    RefPtr<Dispatcher> dispatcher2;
    EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
              dispatcher1->DuplicateBufferHandle(MakeUserPointer(&options),
                                                 &dispatcher2));
    EXPECT_FALSE(dispatcher2);
  }

  EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
}

TEST_F(SharedBufferDispatcherTest, CreateInvalidNumBytes) {
  // Size too big.
  MojoResult result = MOJO_RESULT_INTERNAL;
  auto dispatcher = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions,
      std::numeric_limits<uint64_t>::max(), &result);
  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, result);
  EXPECT_FALSE(dispatcher);

  // Zero size.
  result = MOJO_RESULT_INTERNAL;
  dispatcher = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, 0,
      &result);
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, result);
  EXPECT_FALSE(dispatcher);
}

TEST_F(SharedBufferDispatcherTest, MapBufferInvalidArguments) {
  MojoResult result = MOJO_RESULT_INTERNAL;
  auto dispatcher = SharedBufferDispatcher::Create(
      platform_support(), SharedBufferDispatcher::kDefaultCreateOptions, 100,
      &result);
  EXPECT_EQ(MOJO_RESULT_OK, result);

  std::unique_ptr<PlatformSharedBufferMapping> mapping;
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher->MapBuffer(0, 101, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
  EXPECT_FALSE(mapping);

  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher->MapBuffer(1, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
  EXPECT_FALSE(mapping);

  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher->MapBuffer(0, 0, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
  EXPECT_FALSE(mapping);

  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
}

}  // namespace
}  // namespace system
}  // namespace mojo
