// 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/client/chromoting_client.h"

#include <utility>

#include "remoting/base/capabilities.h"
#include "remoting/base/constants.h"
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/connection_to_host.h"
#include "remoting/protocol/host_stub.h"
#include "remoting/protocol/ice_connection_to_host.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/negotiating_client_authenticator.h"
#include "remoting/protocol/session_config.h"
#include "remoting/protocol/transport_context.h"
#include "remoting/protocol/video_renderer.h"
#include "remoting/protocol/webrtc_connection_to_host.h"
#include "remoting/signaling/jid_util.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"

namespace remoting {

ChromotingClient::ChromotingClient(
    ClientContext* client_context,
    ClientUserInterface* user_interface,
    protocol::VideoRenderer* video_renderer,
    base::WeakPtr<protocol::AudioStub> audio_stream_consumer)
    : user_interface_(user_interface), video_renderer_(video_renderer) {
  DCHECK(client_context->main_task_runner()->BelongsToCurrentThread());

  audio_decode_task_runner_ = client_context->audio_decode_task_runner();
  audio_stream_consumer_ = audio_stream_consumer;
}

ChromotingClient::~ChromotingClient() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (signal_strategy_)
      signal_strategy_->RemoveListener(this);
}

void ChromotingClient::set_protocol_config(
    std::unique_ptr<protocol::CandidateSessionConfig> config) {
  DCHECK(!connection_)
      << "set_protocol_config() cannot be called after Start().";
  protocol_config_ = std::move(config);
}

void ChromotingClient::set_host_experiment_config(
    const std::string& experiment_config) {
  DCHECK(!connection_)
      << "set_host_experiment_config() cannot be called after Start().";
  host_experiment_sender_.reset(new HostExperimentSender(experiment_config));
}

void ChromotingClient::SetConnectionToHostForTests(
    std::unique_ptr<protocol::ConnectionToHost> connection_to_host) {
  connection_ = std::move(connection_to_host);
}

void ChromotingClient::Start(
    SignalStrategy* signal_strategy,
    const protocol::ClientAuthenticationConfig& client_auth_config,
    scoped_refptr<protocol::TransportContext> transport_context,
    const std::string& host_jid,
    const std::string& capabilities) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!session_manager_);  // Start must not be called more than once.

  host_jid_ = NormalizeJid(host_jid);
  local_capabilities_ = capabilities;

  if (!protocol_config_) {
    protocol_config_ = protocol::CandidateSessionConfig::CreateDefault();
  }

  if (!connection_) {
    if (protocol_config_->webrtc_supported()) {
      DCHECK(!protocol_config_->ice_supported());
#if !defined(ENABLE_WEBRTC_REMOTING_CLIENT)
      LOG(FATAL) << "WebRTC is not supported.";
#else
      connection_.reset(new protocol::WebrtcConnectionToHost());
#endif
    } else {
      DCHECK(protocol_config_->ice_supported());
      connection_.reset(new protocol::IceConnectionToHost());
    }
  }
  connection_->set_client_stub(this);
  connection_->set_clipboard_stub(this);
  connection_->set_video_renderer(video_renderer_);

  if (audio_stream_consumer_) {
    connection_->InitializeAudio(audio_decode_task_runner_,
                                 audio_stream_consumer_);
  } else {
    protocol_config_->DisableAudioChannel();
  }

  session_manager_.reset(new protocol::JingleSessionManager(signal_strategy));
  session_manager_->set_protocol_config(std::move(protocol_config_));

  client_auth_config_ = client_auth_config;
  transport_context_ = transport_context;

  signal_strategy_ = signal_strategy;
  signal_strategy_->AddListener(this);

  switch (signal_strategy_->GetState()) {
    case SignalStrategy::CONNECTING:
      // Nothing to do here. Just need to wait until |signal_strategy_| becomes
      // connected.
      break;
    case SignalStrategy::CONNECTED:
      StartConnection();
      break;
    case SignalStrategy::DISCONNECTED:
      signal_strategy_->Connect();
      break;
  }
}

void ChromotingClient::SetCapabilities(
    const protocol::Capabilities& capabilities) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Only accept the first |protocol::Capabilities| message.
  if (host_capabilities_received_) {
    LOG(WARNING) << "protocol::Capabilities has been received already.";
    return;
  }

  host_capabilities_received_ = true;
  if (capabilities.has_capabilities())
    host_capabilities_ = capabilities.capabilities();

  VLOG(1) << "Host capabilities: " << host_capabilities_;

  // Calculate the set of capabilities enabled by both client and host and pass
  // it to the webapp.
  user_interface_->SetCapabilities(
      IntersectCapabilities(local_capabilities_, host_capabilities_));
}

void ChromotingClient::SetPairingResponse(
    const protocol::PairingResponse& pairing_response) {
  DCHECK(thread_checker_.CalledOnValidThread());

  user_interface_->SetPairingResponse(pairing_response);
}

void ChromotingClient::DeliverHostMessage(
    const protocol::ExtensionMessage& message) {
  DCHECK(thread_checker_.CalledOnValidThread());

  user_interface_->DeliverHostMessage(message);
}

void ChromotingClient::SetVideoLayout(const protocol::VideoLayout& layout) {
  int num_video_tracks = layout.video_track_size();
  if (num_video_tracks < 1) {
    LOG(ERROR) << "Received VideoLayout message with 0 tracks.";
    return;
  }

  if (num_video_tracks > 2) {
    LOG(WARNING) << "Received VideoLayout message with " << num_video_tracks
                 << " tracks. Only one track is supported.";
  }

  const protocol::VideoTrackLayout& track_layout = layout.video_track(0);
  int x_dpi = track_layout.has_x_dpi() ? track_layout.x_dpi() : kDefaultDpi;
  int y_dpi = track_layout.has_y_dpi() ? track_layout.y_dpi() : kDefaultDpi;

  webrtc::DesktopSize size_dips(track_layout.width(), track_layout.height());
  webrtc::DesktopSize size_pixels(size_dips.width() * x_dpi / kDefaultDpi,
                                  size_dips.height() * y_dpi / kDefaultDpi);
  user_interface_->SetDesktopSize(size_pixels,
                                  webrtc::DesktopVector(x_dpi, y_dpi));

  mouse_input_scaler_.set_input_size(
      webrtc::DesktopRect::MakeSize(size_pixels));
  mouse_input_scaler_.set_output_size(
      connection_->config().protocol() == protocol::SessionConfig::Protocol::ICE
          ? webrtc::DesktopRect::MakeSize(size_pixels)
          : webrtc::DesktopRect::MakeSize(size_dips));
}

void ChromotingClient::InjectClipboardEvent(
    const protocol::ClipboardEvent& event) {
  DCHECK(thread_checker_.CalledOnValidThread());

  user_interface_->GetClipboardStub()->InjectClipboardEvent(event);
}

void ChromotingClient::SetCursorShape(
    const protocol::CursorShapeInfo& cursor_shape) {
  DCHECK(thread_checker_.CalledOnValidThread());

  user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape);
}

void ChromotingClient::OnConnectionState(
    protocol::ConnectionToHost::State state,
    protocol::ErrorCode error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")";

  if (state == protocol::ConnectionToHost::CONNECTED) {
    OnChannelsConnected();
  }
  user_interface_->OnConnectionState(state, error);
}

void ChromotingClient::OnConnectionReady(bool ready) {
  VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")";
  user_interface_->OnConnectionReady(ready);
}

void ChromotingClient::OnRouteChanged(const std::string& channel_name,
                                      const protocol::TransportRoute& route) {
  VLOG(0) << "Using " << protocol::TransportRoute::GetTypeString(route.type)
          << " connection for " << channel_name << " channel";
  user_interface_->OnRouteChanged(channel_name, route);
}

void ChromotingClient::OnSignalStrategyStateChange(
    SignalStrategy::State state) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (state == SignalStrategy::CONNECTED) {
    VLOG(1) << "Connected as: " << signal_strategy_->GetLocalAddress().jid();
    // After signaling has been connected we can try connecting to the host.
    if (connection_ &&
        connection_->state() == protocol::ConnectionToHost::INITIALIZING) {
      StartConnection();
    }
  } else if (state == SignalStrategy::DISCONNECTED) {
    VLOG(1) << "Signaling connection closed.";
    mouse_input_scaler_.set_input_stub(nullptr);
    connection_.reset();
    user_interface_->OnConnectionState(protocol::ConnectionToHost::CLOSED,
                                       protocol::SIGNALING_ERROR);
  }
}

bool ChromotingClient::OnSignalStrategyIncomingStanza(
    const jingle_xmpp::XmlElement* stanza) {
  return false;
}

void ChromotingClient::StartConnection() {
  DCHECK(thread_checker_.CalledOnValidThread());
  auto session = session_manager_->Connect(
      SignalingAddress(host_jid_),
      std::make_unique<protocol::NegotiatingClientAuthenticator>(
          signal_strategy_->GetLocalAddress().id(), host_jid_,
          client_auth_config_));
  if (host_experiment_sender_) {
    session->AddPlugin(host_experiment_sender_.get());
  }
  connection_->Connect(std::move(session), transport_context_, this);
}

void ChromotingClient::OnChannelsConnected() {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Negotiate capabilities with the host.
  VLOG(1) << "Client capabilities: " << local_capabilities_;

  protocol::Capabilities capabilities;
  capabilities.set_capabilities(local_capabilities_);
  connection_->host_stub()->SetCapabilities(capabilities);

  mouse_input_scaler_.set_input_stub(connection_->input_stub());
}

}  // namespace remoting
