// 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::DesktopSize(size_pixels));
  mouse_input_scaler_.set_output_size(
      connection_->config().protocol() == protocol::SessionConfig::Protocol::ICE
          ? webrtc::DesktopSize(size_pixels)
          : webrtc::DesktopSize(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
