// Copyright 2020 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 "third_party/blink/public/common/messaging/web_message_port.h"

#include "base/memory/ptr_util.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/messaging/string_message_codec.h"
#include "third_party/blink/public/common/messaging/transferable_message.h"
#include "third_party/blink/public/common/messaging/transferable_message_mojom_traits.h"
#include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h"

namespace blink {

WebMessagePort::Message::Message() = default;
WebMessagePort::Message::Message(Message&&) = default;
WebMessagePort::Message& WebMessagePort::Message::operator=(Message&&) =
    default;
WebMessagePort::Message::~Message() = default;

WebMessagePort::Message::Message(const base::string16& data) : data(data) {}

WebMessagePort::Message::Message(std::vector<WebMessagePort> ports)
    : ports(std::move(ports)) {}

WebMessagePort::Message::Message(WebMessagePort&& port) {
  ports.emplace_back(std::move(port));
}

WebMessagePort::Message::Message(const base::string16& data,
                                 std::vector<WebMessagePort> ports)
    : data(data), ports(std::move(ports)) {}

WebMessagePort::Message::Message(const base::string16& data,
                                 WebMessagePort port)
    : data(data) {
  ports.emplace_back(std::move(port));
}

WebMessagePort::MessageReceiver::MessageReceiver() = default;
WebMessagePort::MessageReceiver::~MessageReceiver() = default;

bool WebMessagePort::MessageReceiver::OnMessage(Message) {
  return false;
}

WebMessagePort::WebMessagePort() = default;

WebMessagePort::WebMessagePort(WebMessagePort&& other) {
  Take(std::move(other));
}

WebMessagePort& WebMessagePort::operator=(WebMessagePort&& other) {
  CloseIfNecessary();
  Take(std::move(other));
  return *this;
}

WebMessagePort::~WebMessagePort() {
  CloseIfNecessary();
}

// static
std::pair<WebMessagePort, WebMessagePort> WebMessagePort::CreatePair() {
  MessagePortDescriptorPair port_pair;
  return std::make_pair(WebMessagePort(port_pair.TakePort0()),
                        WebMessagePort(port_pair.TakePort1()));
}

void WebMessagePort::SetReceiver(
    MessageReceiver* receiver,
    scoped_refptr<base::SequencedTaskRunner> runner) {
  DCHECK(receiver);
  DCHECK(runner.get());

  DCHECK(port_.IsValid());
  DCHECK(!connector_);
  DCHECK(!is_closed_);
  DCHECK(!is_errored_);
  DCHECK(is_transferable_);

  is_transferable_ = false;
  receiver_ = receiver;
  connector_ = std::make_unique<mojo::Connector>(
      port_.TakeHandleToEntangleWithEmbedder(),
      mojo::Connector::SINGLE_THREADED_SEND, std::move(runner));
  connector_->set_incoming_receiver(this);
  connector_->set_connection_error_handler(
      base::BindOnce(&WebMessagePort::OnPipeError, base::Unretained(this)));
}

void WebMessagePort::ClearReceiver() {
  if (!connector_)
    return;
  port_.GiveDisentangledHandle(connector_->PassMessagePipe());
  connector_.reset();
  receiver_ = nullptr;
}

base::SequencedTaskRunner* WebMessagePort::GetTaskRunner() const {
  if (!connector_)
    return nullptr;
  return connector_->task_runner();
}

MessagePortDescriptor WebMessagePort::PassPort() {
  DCHECK(is_transferable_);

  // Clear the receiver, which takes the handle out of the connector if it
  // exists, and puts it back in |port_|.
  ClearReceiver();
  MessagePortDescriptor port = std::move(port_);
  Reset();
  return port;
}

WebMessagePort::WebMessagePort(MessagePortDescriptor&& port)
    : port_(std::move(port)), is_closed_(false), is_transferable_(true) {
  DCHECK(port_.IsValid());
}

bool WebMessagePort::CanPostMessage() const {
  return connector_ && connector_->is_valid() && !is_closed_ && !is_errored_ &&
         receiver_;
}

bool WebMessagePort::PostMessage(Message&& message) {
  if (!CanPostMessage())
    return false;

  // Extract the underlying handles for transport in a
  // blink::TransferableMessage.
  std::vector<MessagePortDescriptor> ports;
  for (auto& port : message.ports) {
    // We should not be trying to send ourselves in a message. Mojo prevents
    // this at a deeper level, but we can also check here.
    DCHECK_NE(this, &port);

    ports.emplace_back(port.PassPort());
  }

  // Build the message.
  // TODO(chrisha): Finally kill off MessagePortChannel, once
  // MessagePortDescriptor more thoroughly plays that role.
  blink::TransferableMessage transferable_message;
  transferable_message.owned_encoded_message =
      blink::EncodeStringMessage(message.data);
  transferable_message.encoded_message =
      transferable_message.owned_encoded_message;
  transferable_message.ports =
      blink::MessagePortChannel::CreateFromHandles(std::move(ports));

  // TODO(chrisha): Notify the instrumentation delegate of a message being sent!

  // Send via Mojo. The message should never be malformed so should always be
  // accepted.
  mojo::Message mojo_message =
      blink::mojom::TransferableMessage::SerializeAsMessage(
          &transferable_message);
  CHECK(connector_->Accept(&mojo_message));

  return true;
}

bool WebMessagePort::IsValid() const {
  if (connector_)
    return connector_->is_valid();
  return port_.IsValid();
}

void WebMessagePort::Close() {
  CloseIfNecessary();
}

void WebMessagePort::Reset() {
  CloseIfNecessary();
  is_closed_ = true;
  is_errored_ = false;
  is_transferable_ = false;
}

void WebMessagePort::Take(WebMessagePort&& other) {
  port_ = std::move(other.port_);
  connector_ = std::move(other.connector_);
  is_closed_ = std::exchange(other.is_closed_, true);
  is_errored_ = std::exchange(other.is_errored_, false);
  is_transferable_ = std::exchange(other.is_transferable_, false);
  receiver_ = std::exchange(other.receiver_, nullptr);
}

void WebMessagePort::OnPipeError() {
  DCHECK(!is_transferable_);
  if (is_errored_)
    return;
  is_errored_ = true;
  if (receiver_)
    receiver_->OnPipeError();
}

void WebMessagePort::CloseIfNecessary() {
  if (is_closed_)
    return;
  is_closed_ = true;
  ClearReceiver();
  port_.Reset();
}

bool WebMessagePort::Accept(mojo::Message* mojo_message) {
  DCHECK(receiver_);
  DCHECK(!is_transferable_);

  // Deserialize the message.
  blink::TransferableMessage transferable_message;
  if (!blink::mojom::TransferableMessage::DeserializeFromMessage(
          std::move(*mojo_message), &transferable_message)) {
    return false;
  }

  // Decode the string portion of the message.
  Message message;
  if (!blink::DecodeStringMessage(transferable_message.encoded_message,
                                  &message.data)) {
    return false;
  }

  // Convert raw handles to MessagePorts.
  // TODO(chrisha): Kill off MessagePortChannel entirely!
  auto handles =
      blink::MessagePortChannel::ReleaseHandles(transferable_message.ports);
  for (auto& handle : handles) {
    message.ports.emplace_back(WebMessagePort(std::move(handle)));
  }

  // Pass the message on to the receiver.
  return receiver_->OnMessage(std::move(message));
}

}  // namespace blink
