// 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 <utility>

#include "base/logging.h"
#include "mojo/edk/embedder/platform_support.h"
#include "mojo/edk/platform/platform_shared_buffer.h"
#include "mojo/edk/system/channel.h"
#include "mojo/edk/system/configuration.h"
#include "mojo/edk/system/memory.h"
#include "mojo/edk/system/options_validation.h"
#include "mojo/public/c/system/macros.h"

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

namespace mojo {
namespace system {

namespace {

struct MOJO_ALIGNAS(8) SerializedSharedBufferDispatcher {
  uint64_t num_bytes;
  uint32_t platform_handle_index;
};

}  // namespace

// static
constexpr MojoHandleRights SharedBufferDispatcher::kDefaultHandleRights;

// static
const MojoCreateSharedBufferOptions
    SharedBufferDispatcher::kDefaultCreateOptions = {
        static_cast<uint32_t>(sizeof(MojoCreateSharedBufferOptions)),
        MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE};

// static
MojoResult SharedBufferDispatcher::ValidateCreateOptions(
    UserPointer<const MojoCreateSharedBufferOptions> in_options,
    MojoCreateSharedBufferOptions* out_options) {
  const MojoCreateSharedBufferOptionsFlags kKnownFlags =
      MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE;

  *out_options = kDefaultCreateOptions;
  if (in_options.IsNull())
    return MOJO_RESULT_OK;

  UserOptionsReader<MojoCreateSharedBufferOptions> reader(in_options);
  if (!reader.is_valid())
    return MOJO_RESULT_INVALID_ARGUMENT;

  if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateSharedBufferOptions, flags, reader))
    return MOJO_RESULT_OK;
  if ((reader.options().flags & ~kKnownFlags))
    return MOJO_RESULT_UNIMPLEMENTED;
  out_options->flags = reader.options().flags;

  // Checks for fields beyond |flags|:

  // (Nothing here yet.)

  return MOJO_RESULT_OK;
}

// static
RefPtr<SharedBufferDispatcher> SharedBufferDispatcher::Create(
    embedder::PlatformSupport* platform_support,
    const MojoCreateSharedBufferOptions& /*validated_options*/,
    uint64_t num_bytes,
    MojoResult* result) {
  if (!num_bytes) {
    *result = MOJO_RESULT_INVALID_ARGUMENT;
    return nullptr;
  }
  if (num_bytes > GetConfiguration().max_shared_memory_num_bytes) {
    *result = MOJO_RESULT_RESOURCE_EXHAUSTED;
    return nullptr;
  }

  auto shared_buffer =
      platform_support->CreateSharedBuffer(static_cast<size_t>(num_bytes));
  if (!shared_buffer) {
    *result = MOJO_RESULT_RESOURCE_EXHAUSTED;
    return nullptr;
  }

  *result = MOJO_RESULT_OK;
  return CreateInternal(std::move(shared_buffer));
}

Dispatcher::Type SharedBufferDispatcher::GetType() const {
  return Type::SHARED_BUFFER;
}

bool SharedBufferDispatcher::SupportsEntrypointClass(
    EntrypointClass entrypoint_class) const {
  return (entrypoint_class == EntrypointClass::NONE ||
          entrypoint_class == EntrypointClass::BUFFER);
}

// static
RefPtr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize(
    Channel* channel,
    const void* source,
    size_t size,
    std::vector<ScopedPlatformHandle>* platform_handles) {
  DCHECK(channel);

  if (size != sizeof(SerializedSharedBufferDispatcher)) {
    LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)";
    return nullptr;
  }

  const SerializedSharedBufferDispatcher* serialization =
      static_cast<const SerializedSharedBufferDispatcher*>(source);

  if (serialization->num_bytes >
      static_cast<uint64_t>(std::numeric_limits<size_t>::max())) {
    LOG(ERROR)
        << "Invalid serialized shared buffer dispatcher (num_bytes too large)";
    return nullptr;
  }

  if (static_cast<size_t>(serialization->platform_handle_index) >
      std::numeric_limits<size_t>::max()) {
    LOG(ERROR) << "Invalid serialized shared buffer dispatcher"
                  " (platform_handle_index too large)";
    return nullptr;
  }

  size_t num_bytes = static_cast<size_t>(serialization->num_bytes);
  size_t platform_handle_index =
      static_cast<size_t>(serialization->platform_handle_index);

  if (!num_bytes) {
    LOG(ERROR)
        << "Invalid serialized shared buffer dispatcher (invalid num_bytes)";
    return nullptr;
  }

  if (!platform_handles || platform_handle_index >= platform_handles->size()) {
    LOG(ERROR)
        << "Invalid serialized shared buffer dispatcher (missing handles)";
    return nullptr;
  }

  // Starts off invalid, which is what we want.
  ScopedPlatformHandle platform_handle;
  // We take ownership of the handle, so we have to invalidate the one in
  // |platform_handles|.
  std::swap(platform_handle, (*platform_handles)[platform_handle_index]);

  // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be
  // closed even if creation fails.
  auto shared_buffer =
      channel->platform_support()->CreateSharedBufferFromHandle(
          num_bytes, std::move(platform_handle));
  if (!shared_buffer) {
    LOG(ERROR)
        << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)";
    return nullptr;
  }

  return CreateInternal(std::move(shared_buffer));
}

SharedBufferDispatcher::SharedBufferDispatcher(
    RefPtr<PlatformSharedBuffer>&& shared_buffer)
    : shared_buffer_(std::move(shared_buffer)) {
  DCHECK(shared_buffer_);
}

SharedBufferDispatcher::~SharedBufferDispatcher() {
}

// static
MojoResult SharedBufferDispatcher::ValidateDuplicateOptions(
    UserPointer<const MojoDuplicateBufferHandleOptions> in_options,
    MojoDuplicateBufferHandleOptions* out_options) {
  const MojoDuplicateBufferHandleOptionsFlags kKnownFlags =
      MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE;
  static const MojoDuplicateBufferHandleOptions kDefaultOptions = {
      static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)),
      MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE};

  *out_options = kDefaultOptions;
  if (in_options.IsNull())
    return MOJO_RESULT_OK;

  UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options);
  if (!reader.is_valid())
    return MOJO_RESULT_INVALID_ARGUMENT;

  if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags,
                                 reader))
    return MOJO_RESULT_OK;
  if ((reader.options().flags & ~kKnownFlags))
    return MOJO_RESULT_UNIMPLEMENTED;
  out_options->flags = reader.options().flags;

  // Checks for fields beyond |flags|:

  // (Nothing here yet.)

  return MOJO_RESULT_OK;
}

void SharedBufferDispatcher::CloseImplNoLock() {
  mutex().AssertHeld();
  DCHECK(shared_buffer_);
  shared_buffer_ = nullptr;
}

RefPtr<Dispatcher>
SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock(
    MessagePipe* /*message_pipe*/,
    unsigned /*port*/) {
  mutex().AssertHeld();

  CancelAllAwakablesNoLock();

  DCHECK(shared_buffer_);
  return CreateInternal(std::move(shared_buffer_));
}

MojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock(
    UserPointer<const MojoDuplicateBufferHandleOptions> options,
    RefPtr<Dispatcher>* new_dispatcher) {
  mutex().AssertHeld();

  MojoDuplicateBufferHandleOptions validated_options;
  MojoResult result = ValidateDuplicateOptions(options, &validated_options);
  if (result != MOJO_RESULT_OK)
    return result;

  // Note: Since this is "duplicate", we keep our ref to |shared_buffer_|.
  *new_dispatcher = CreateInternal(shared_buffer_.Clone());
  return MOJO_RESULT_OK;
}

MojoResult SharedBufferDispatcher::GetBufferInformationImplNoLock(
    UserPointer<MojoBufferInformation> info,
    uint32_t info_num_bytes) {
  mutex().AssertHeld();

  // Note: If/when |MojoBufferInformation| is extended beyond its initial
  // definition, more work will be necessary. (See the definition of
  // |MojoGetBufferInformation()| in mojo/public/c/system/buffer.h.)
  static_assert(sizeof(MojoBufferInformation) == 16u,
                "MojoBufferInformation has been extended!");

  if (info_num_bytes < sizeof(MojoBufferInformation))
    return MOJO_RESULT_INVALID_ARGUMENT;

  MojoBufferInformation model_info = {
      sizeof(MojoBufferInformation),                         // |struct_size|.
      MOJO_BUFFER_INFORMATION_FLAG_NONE,                     // |flags|.
      static_cast<uint64_t>(shared_buffer_->GetNumBytes()),  // |num_bytes|.
  };
  info.Put(model_info);
  return MOJO_RESULT_OK;
}

MojoResult SharedBufferDispatcher::MapBufferImplNoLock(
    uint64_t offset,
    uint64_t num_bytes,
    MojoMapBufferFlags flags,
    std::unique_ptr<PlatformSharedBufferMapping>* mapping) {
  mutex().AssertHeld();
  DCHECK(shared_buffer_);

  if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max()))
    return MOJO_RESULT_INVALID_ARGUMENT;
  if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max()))
    return MOJO_RESULT_INVALID_ARGUMENT;

  if (!shared_buffer_->IsValidMap(static_cast<size_t>(offset),
                                  static_cast<size_t>(num_bytes)))
    return MOJO_RESULT_INVALID_ARGUMENT;

  DCHECK(mapping);
  *mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset),
                                        static_cast<size_t>(num_bytes));
  if (!*mapping)
    return MOJO_RESULT_RESOURCE_EXHAUSTED;

  return MOJO_RESULT_OK;
}

void SharedBufferDispatcher::StartSerializeImplNoLock(
    Channel* /*channel*/,
    size_t* max_size,
    size_t* max_platform_handles) {
  AssertHasOneRef();  // Only one ref => no need to take the lock.
  *max_size = sizeof(SerializedSharedBufferDispatcher);
  *max_platform_handles = 1;
}

bool SharedBufferDispatcher::EndSerializeAndCloseImplNoLock(
    Channel* /*channel*/,
    void* destination,
    size_t* actual_size,
    std::vector<ScopedPlatformHandle>* platform_handles) {
  AssertHasOneRef();  // Only one ref => no need to take the lock.
  DCHECK(shared_buffer_);

  SerializedSharedBufferDispatcher* serialization =
      static_cast<SerializedSharedBufferDispatcher*>(destination);
  // If there's only one reference to |shared_buffer_|, then it's ours (and no
  // one else can make any more references to it), so we can just take its
  // handle.
  ScopedPlatformHandle platform_handle(
      shared_buffer_->HasOneRef() ? shared_buffer_->PassPlatformHandle()
                                  : shared_buffer_->DuplicatePlatformHandle());
  if (!platform_handle.is_valid()) {
    shared_buffer_ = nullptr;
    return false;
  }

  serialization->num_bytes = shared_buffer_->GetNumBytes();
  serialization->platform_handle_index = platform_handles->size();
  platform_handles->push_back(std::move(platform_handle));
  *actual_size = sizeof(SerializedSharedBufferDispatcher);

  shared_buffer_ = nullptr;

  return true;
}

}  // namespace system
}  // namespace mojo
