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

#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "remoting/base/constants.h"
#include "remoting/jingle_glue/signal_strategy.h"
#include "remoting/protocol/audio_reader.h"
#include "remoting/protocol/audio_stub.h"
#include "remoting/protocol/auth_util.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/client_control_dispatcher.h"
#include "remoting/protocol/client_event_dispatcher.h"
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/errors.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/transport.h"
#include "remoting/protocol/video_reader.h"
#include "remoting/protocol/video_stub.h"

namespace remoting {
namespace protocol {

ConnectionToHost::ConnectionToHost(
    bool allow_nat_traversal)
    : allow_nat_traversal_(allow_nat_traversal),
      event_callback_(NULL),
      client_stub_(NULL),
      clipboard_stub_(NULL),
      audio_stub_(NULL),
      signal_strategy_(NULL),
      state_(INITIALIZING),
      error_(OK) {
}

ConnectionToHost::~ConnectionToHost() {
  CloseChannels();

  if (session_.get())
    session_.reset();

  if (session_manager_.get())
    session_manager_.reset();

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

void ConnectionToHost::Connect(SignalStrategy* signal_strategy,
                               scoped_ptr<TransportFactory> transport_factory,
                               scoped_ptr<Authenticator> authenticator,
                               const std::string& host_jid,
                               const std::string& host_public_key,
                               HostEventCallback* event_callback) {
  DCHECK(client_stub_);
  DCHECK(clipboard_stub_);
  DCHECK(monitored_video_stub_);

  signal_strategy_ = signal_strategy;
  event_callback_ = event_callback;
  authenticator_ = authenticator.Pass();

  // Save jid of the host. The actual connection is created later after
  // |signal_strategy_| is connected.
  host_jid_ = host_jid;
  host_public_key_ = host_public_key;

  signal_strategy_->AddListener(this);
  signal_strategy_->Connect();

  session_manager_.reset(new JingleSessionManager(transport_factory.Pass()));
  session_manager_->Init(signal_strategy_, this);

  SetState(CONNECTING, OK);
}

const SessionConfig& ConnectionToHost::config() {
  return session_->config();
}

ClipboardStub* ConnectionToHost::clipboard_forwarder() {
  return &clipboard_forwarder_;
}

HostStub* ConnectionToHost::host_stub() {
  // TODO(wez): Add a HostFilter class, equivalent to input filter.
  return control_dispatcher_.get();
}

InputStub* ConnectionToHost::input_stub() {
  return &event_forwarder_;
}

void ConnectionToHost::set_client_stub(ClientStub* client_stub) {
  client_stub_ = client_stub;
}

void ConnectionToHost::set_clipboard_stub(ClipboardStub* clipboard_stub) {
  clipboard_stub_ = clipboard_stub;
}

void ConnectionToHost::set_video_stub(VideoStub* video_stub) {
  DCHECK(video_stub);
  monitored_video_stub_.reset(new MonitoredVideoStub(
      video_stub,
      base::TimeDelta::FromSeconds(
          MonitoredVideoStub::kConnectivityCheckDelaySeconds),
      base::Bind(&ConnectionToHost::OnVideoChannelStatus,
                 base::Unretained(this))));
}

void ConnectionToHost::set_audio_stub(AudioStub* audio_stub) {
  audio_stub_ = audio_stub;
}

void ConnectionToHost::OnSignalStrategyStateChange(
    SignalStrategy::State state) {
  DCHECK(CalledOnValidThread());
  DCHECK(event_callback_);

  if (state == SignalStrategy::CONNECTED) {
    VLOG(1) << "Connected as: " << signal_strategy_->GetLocalJid();
  } else if (state == SignalStrategy::DISCONNECTED) {
    VLOG(1) << "Connection closed.";
    CloseOnError(SIGNALING_ERROR);
  }
}

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

void ConnectionToHost::OnSessionManagerReady() {
  DCHECK(CalledOnValidThread());

  // After SessionManager is initialized we can try to connect to the host.
  scoped_ptr<CandidateSessionConfig> candidate_config =
      CandidateSessionConfig::CreateDefault();
  if (!audio_stub_) {
    candidate_config->DisableAudioChannel();
  }
  candidate_config->EnableVideoCodec(ChannelConfig::CODEC_VP9);

  session_ = session_manager_->Connect(
      host_jid_, authenticator_.Pass(), candidate_config.Pass());
  session_->SetEventHandler(this);
}

void ConnectionToHost::OnIncomingSession(
    Session* session,
    SessionManager::IncomingSessionResponse* response) {
  DCHECK(CalledOnValidThread());
  // Client always rejects incoming sessions.
  *response = SessionManager::DECLINE;
}

void ConnectionToHost::OnSessionStateChange(
    Session::State state) {
  DCHECK(CalledOnValidThread());
  DCHECK(event_callback_);

  switch (state) {
    case Session::INITIALIZING:
    case Session::CONNECTING:
    case Session::ACCEPTING:
    case Session::CONNECTED:
    case Session::AUTHENTICATING:
      // Don't care about these events.
      break;

    case Session::AUTHENTICATED:
      SetState(AUTHENTICATED, OK);

      control_dispatcher_.reset(new ClientControlDispatcher());
      control_dispatcher_->Init(
          session_.get(), session_->config().control_config(),
          base::Bind(&ConnectionToHost::OnChannelInitialized,
                     base::Unretained(this)));
      control_dispatcher_->set_client_stub(client_stub_);
      control_dispatcher_->set_clipboard_stub(clipboard_stub_);

      event_dispatcher_.reset(new ClientEventDispatcher());
      event_dispatcher_->Init(
          session_.get(), session_->config().event_config(),
          base::Bind(&ConnectionToHost::OnChannelInitialized,
                     base::Unretained(this)));

      video_reader_ = VideoReader::Create(session_->config());
      video_reader_->Init(session_.get(), monitored_video_stub_.get(),
                          base::Bind(&ConnectionToHost::OnChannelInitialized,
                                     base::Unretained(this)));

      audio_reader_ = AudioReader::Create(session_->config());
      if (audio_reader_.get()) {
        audio_reader_->Init(session_.get(), session_->config().audio_config(),
                            base::Bind(&ConnectionToHost::OnChannelInitialized,
                                       base::Unretained(this)));
        audio_reader_->set_audio_stub(audio_stub_);
      }
      break;

    case Session::CLOSED:
      CloseChannels();
      SetState(CLOSED, OK);
      break;

    case Session::FAILED:
      // If we were connected then treat signaling timeout error as if
      // the connection was closed by the peer.
      //
      // TODO(sergeyu): This logic belongs to the webapp, but we
      // currently don't expose this error code to the webapp, and it
      // would be hard to add it because client plugin and webapp
      // versions may not be in sync. It should be easy to do after we
      // are finished moving the client plugin to NaCl.
      if (state_ == CONNECTED && session_->error() == SIGNALING_TIMEOUT) {
        CloseChannels();
        SetState(CLOSED, OK);
      } else {
        CloseOnError(session_->error());
      }
      break;
  }
}

void ConnectionToHost::OnSessionRouteChange(const std::string& channel_name,
                                            const TransportRoute& route) {
  event_callback_->OnRouteChanged(channel_name, route);
}

void ConnectionToHost::OnVideoChannelStatus(bool active) {
  event_callback_->OnConnectionReady(active);
}

ConnectionToHost::State ConnectionToHost::state() const {
  return state_;
}

void ConnectionToHost::OnChannelInitialized(bool successful) {
  if (!successful) {
    LOG(ERROR) << "Failed to connect video channel";
    CloseOnError(CHANNEL_CONNECTION_ERROR);
    return;
  }

  NotifyIfChannelsReady();
}

void ConnectionToHost::NotifyIfChannelsReady() {
  if (!control_dispatcher_.get() || !control_dispatcher_->is_connected())
    return;
  if (!event_dispatcher_.get() || !event_dispatcher_->is_connected())
    return;
  if (!video_reader_.get() || !video_reader_->is_connected())
    return;
  if ((!audio_reader_.get() || !audio_reader_->is_connected()) &&
      session_->config().is_audio_enabled()) {
    return;
  }
  if (state_ != AUTHENTICATED)
    return;

  // Start forwarding clipboard and input events.
  clipboard_forwarder_.set_clipboard_stub(control_dispatcher_.get());
  event_forwarder_.set_input_stub(event_dispatcher_.get());
  SetState(CONNECTED, OK);
}

void ConnectionToHost::CloseOnError(ErrorCode error) {
  CloseChannels();
  SetState(FAILED, error);
}

void ConnectionToHost::CloseChannels() {
  control_dispatcher_.reset();
  event_dispatcher_.reset();
  clipboard_forwarder_.set_clipboard_stub(NULL);
  event_forwarder_.set_input_stub(NULL);
  video_reader_.reset();
  audio_reader_.reset();
}

void ConnectionToHost::SetState(State state, ErrorCode error) {
  DCHECK(CalledOnValidThread());
  // |error| should be specified only when |state| is set to FAILED.
  DCHECK(state == FAILED || error == OK);

  if (state != state_) {
    state_ = state;
    error_ = error;
    event_callback_->OnConnectionState(state_, error_);
  }
}

}  // namespace protocol
}  // namespace remoting
