// 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 "base/memory/ptr_util.h"
#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_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_consumer_ = audio_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_consumer_) {
    connection_->InitializeAudio(audio_decode_task_runner_, audio_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(size_pixels);
  mouse_input_scaler_.set_output_size(
      connection_->config().protocol() == protocol::SessionConfig::Protocol::ICE
          ? size_pixels
          : 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.";
    connection_.reset();
    user_interface_->OnConnectionState(protocol::ConnectionToHost::CLOSED,
                                       protocol::SIGNALING_ERROR);
  }
}

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

void ChromotingClient::StartConnection() {
  DCHECK(thread_checker_.CalledOnValidThread());
  auto session = session_manager_->Connect(
      SignalingAddress(host_jid_),
      base::MakeUnique<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
