// Copyright 2019 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 <list>

#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "mojo/core/channel.h"
#include "mojo/core/entrypoints.h"
#include "mojo/core/test/data/channel_mac/channel_mac.pb.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "testing/libfuzzer/fuzzers/mach/mach_message_converter.h"
#include "testing/libfuzzer/proto/lpm_interface.h"

namespace {

class ChannelMacFuzzer {
 public:
  ChannelMacFuzzer() {
    mojo::core::InitializeCore();

    logging::SetMinLogLevel(logging::LOG_FATAL);
  }

  scoped_refptr<base::TaskRunner> io_task_runner() {
    return io_task_executor_.task_runner();
  }

 private:
  base::SingleThreadTaskExecutor io_task_executor_{base::MessagePumpType::IO};
};

class FakeChannelDelegate : public mojo::core::Channel::Delegate {
 public:
  FakeChannelDelegate() = default;
  ~FakeChannelDelegate() override = default;

  void OnChannelMessage(const void* payload,
                        size_t payload_size,
                        std::vector<mojo::PlatformHandle> handles) override {}
  void OnChannelError(mojo::core::Channel::Error error) override {}
};

}  // namespace

DEFINE_BINARY_PROTO_FUZZER(mojo_fuzzer::ChannelMac proto) {
  static ChannelMacFuzzer environment;

  mojo::PlatformChannel platform_channel;
  mojo::PlatformChannelEndpoint fuzzed_endpoint;
  mojo::PlatformChannelEndpoint other_endpoint;

  mach_port_t send_port = platform_channel.local_endpoint()
                              .platform_handle()
                              .GetMachSendRight()
                              .get();

  if (proto.endpoint_type() == mojo_fuzzer::ChannelMac_EndpointType_LOCAL) {
    fuzzed_endpoint = platform_channel.TakeLocalEndpoint();
    other_endpoint = platform_channel.TakeRemoteEndpoint();
  } else if (proto.endpoint_type() ==
             mojo_fuzzer::ChannelMac_EndpointType_REMOTE) {
    fuzzed_endpoint = platform_channel.TakeRemoteEndpoint();
    other_endpoint = platform_channel.TakeLocalEndpoint();
  }

  FakeChannelDelegate delegate;

  auto channel = mojo::core::Channel::Create(
      &delegate, mojo::core::ConnectionParams(std::move(fuzzed_endpoint)),
      mojo::core::Channel::HandlePolicy::kAcceptHandles,
      environment.io_task_runner());
  channel->Start();

  // If the handshake is not being fuzzed, establish a peer Channel that will
  // put |channel| into a good state by performing the handshake.
  scoped_refptr<mojo::core::Channel> peer_channel;
  if (!proto.fuzz_handshake()) {
    peer_channel = mojo::core::Channel::Create(
        &delegate, mojo::core::ConnectionParams(std::move(other_endpoint)),
        mojo::core::Channel::HandlePolicy::kAcceptHandles,
        environment.io_task_runner());
    peer_channel->Start();
  }

  base::RunLoop().RunUntilIdle();

  // Save off any ports that were sent as part of a message until after the
  // channel has been shut down.
  std::list<mach_fuzzer::SendablePort> ports_to_destroy;

  for (auto& message : *proto.mutable_messages()) {
    if (message.HasExtension(mojo_fuzzer::MojoMessage::mojo_message)) {
      // Mojo message data for inline Mach messages is
      // [data_length_uint64][data_bytes].
      const auto& mojo_message =
          message.GetExtension(mojo_fuzzer::MojoMessage::mojo_message);

      // If the fuzz data do not specify an explicit length, just use the byte
      // length.
      uint64_t data_length = mojo_message.has_data_length()
                                 ? mojo_message.data_length()
                                 : mojo_message.data().size();
      std::string data;
      data.append(reinterpret_cast<const char*>(&data_length),
                  sizeof(data_length));
      data.append(mojo_message.data().begin(), mojo_message.data().end());
      message.set_data(data);
    }

    mach_fuzzer::SendResult result = SendMessage(send_port, message);

    std::move(result.message.ports.begin(), result.message.ports.end(),
              std::back_inserter(ports_to_destroy));
  }

  base::RunLoop().RunUntilIdle();

  channel->ShutDown();
  channel.reset();

  if (peer_channel) {
    peer_channel->ShutDown();
    peer_channel.reset();
  }

  base::RunLoop().RunUntilIdle();
}
