// Copyright (c) 2012 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 "remoting/protocol/host_control_dispatcher.h"

#include "base/callback_helpers.h"
#include "net/socket/stream_socket.h"
#include "remoting/base/compound_buffer.h"
#include "remoting/base/constants.h"
#include "remoting/proto/control.pb.h"
#include "remoting/proto/internal.pb.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/host_stub.h"
#include "remoting/protocol/message_pipe.h"
#include "remoting/protocol/message_serialization.h"

namespace remoting {
namespace protocol {

HostControlDispatcher::HostControlDispatcher()
    : ChannelDispatcherBase(kControlChannelName) {}
HostControlDispatcher::~HostControlDispatcher() = default;

void HostControlDispatcher::SetCapabilities(
    const Capabilities& capabilities) {
  ControlMessage message;
  message.mutable_capabilities()->CopyFrom(capabilities);
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::SetPairingResponse(
    const PairingResponse& pairing_response) {
  ControlMessage message;
  message.mutable_pairing_response()->CopyFrom(pairing_response);
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::DeliverHostMessage(
    const ExtensionMessage& message) {
  ControlMessage control_message;
  control_message.mutable_extension_message()->CopyFrom(message);
  message_pipe()->Send(&control_message, {});
}

void HostControlDispatcher::SetVideoLayout(const VideoLayout& layout) {
  ControlMessage message;
  message.mutable_video_layout()->CopyFrom(layout);
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::SetTransportInfo(
    const TransportInfo& transport_info) {
  ControlMessage message;
  message.mutable_transport_info()->CopyFrom(transport_info);
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::InjectClipboardEvent(const ClipboardEvent& event) {
  ControlMessage message;
  message.mutable_clipboard_event()->CopyFrom(event);
  std::size_t message_size = message.ByteSizeLong();
  if (message_size > max_message_size_) {
    // Better to drop the event than drop the connection, which can happen if
    // the browser receives a message larger than it can handle.
    LOG(WARNING) << "Clipboard message dropped because message size "
                 << message_size << " is larger than " << max_message_size_;
    return;
  }
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::SetCursorShape(
    const CursorShapeInfo& cursor_shape) {
  ControlMessage message;
  message.mutable_cursor_shape()->CopyFrom(cursor_shape);
  std::size_t message_size = message.ByteSizeLong();
  if (message_size > max_message_size_) {
    // Better to drop the event than drop the connection, which can happen if
    // the browser receives a message larger than it can handle.
    LOG(WARNING) << "Cursor message dropped because message size "
                 << message_size << " is larger than " << max_message_size_;
    return;
  }
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::SetKeyboardLayout(const KeyboardLayout& layout) {
  ControlMessage message;
  message.mutable_keyboard_layout()->CopyFrom(layout);
  message_pipe()->Send(&message, {});
}

void HostControlDispatcher::OnIncomingMessage(
    std::unique_ptr<CompoundBuffer> buffer) {
  DCHECK(clipboard_stub_);
  DCHECK(host_stub_);

  std::unique_ptr<ControlMessage> message =
      ParseMessage<ControlMessage>(buffer.get());
  if (!message)
    return;

  // TODO(sergeyu): Move message validation from the message handlers here.
  if (message->has_clipboard_event()) {
    clipboard_stub_->InjectClipboardEvent(message->clipboard_event());
  } else if (message->has_client_resolution()) {
    const ClientResolution& resolution = message->client_resolution();
    if ((resolution.has_dips_width() && resolution.dips_width() <= 0) ||
        (resolution.has_dips_height() && resolution.dips_height() <= 0)) {
      LOG(ERROR) << "Received invalid ClientResolution message.";
      return;
    }
    host_stub_->NotifyClientResolution(resolution);
  } else if (message->has_video_control()) {
    host_stub_->ControlVideo(message->video_control());
  } else if (message->has_audio_control()) {
    host_stub_->ControlAudio(message->audio_control());
  } else if (message->has_capabilities()) {
    host_stub_->SetCapabilities(message->capabilities());
  } else if (message->has_pairing_request()) {
    host_stub_->RequestPairing(message->pairing_request());
  } else if (message->has_extension_message()) {
    host_stub_->DeliverClientMessage(message->extension_message());
  } else if (message->has_select_display()) {
    host_stub_->SelectDesktopDisplay(message->select_display());
  } else if (message->has_peer_connection_parameters()) {
    host_stub_->ControlPeerConnection(message->peer_connection_parameters());
  } else {
    LOG(WARNING) << "Unknown control message received.";
  }
}

}  // namespace protocol
}  // namespace remoting
