// Copyright 2015 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/ice_connection_to_host.h"

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/audio_decode_scheduler.h"
#include "remoting/protocol/audio_reader.h"
#include "remoting/protocol/audio_stub.h"
#include "remoting/protocol/auth_util.h"
#include "remoting/protocol/client_control_dispatcher.h"
#include "remoting/protocol/client_event_dispatcher.h"
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/client_video_dispatcher.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/errors.h"
#include "remoting/protocol/ice_transport.h"
#include "remoting/protocol/transport_context.h"
#include "remoting/protocol/video_renderer.h"

namespace remoting {
namespace protocol {

IceConnectionToHost::IceConnectionToHost() = default;
IceConnectionToHost::~IceConnectionToHost() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void IceConnectionToHost::Connect(
    std::unique_ptr<Session> session,
    scoped_refptr<TransportContext> transport_context,
    HostEventCallback* event_callback) {
  DCHECK(client_stub_);
  DCHECK(clipboard_stub_);
  DCHECK(video_renderer_);

  transport_.reset(new IceTransport(transport_context, this));

  session_ = std::move(session);
  session_->SetEventHandler(this);
  session_->SetTransport(transport_.get());

  event_callback_ = event_callback;

  SetState(CONNECTING, OK);
}

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

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

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

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

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

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

void IceConnectionToHost::set_video_renderer(VideoRenderer* video_renderer) {
  DCHECK(video_renderer);
  DCHECK(!monitored_video_stub_);
  video_renderer_ = video_renderer;
}

void IceConnectionToHost::InitializeAudio(
    scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
    base::WeakPtr<AudioStub> audio_stub) {
  audio_decode_scheduler_.reset(
      new AudioDecodeScheduler(audio_decode_task_runner, audio_stub));
}

void IceConnectionToHost::OnSessionStateChange(Session::State state) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(event_callback_);

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

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

      // Setup control channel.
      control_dispatcher_.reset(new ClientControlDispatcher());
      control_dispatcher_->Init(transport_->GetMultiplexedChannelFactory(),
                                this);
      control_dispatcher_->set_client_stub(client_stub_);
      control_dispatcher_->set_clipboard_stub(clipboard_stub_);

      // Setup event channel.
      event_dispatcher_.reset(new ClientEventDispatcher());
      event_dispatcher_->Init(transport_->GetMultiplexedChannelFactory(), this);

      // Configure video pipeline.
      video_renderer_->OnSessionConfig(session_->config());
      monitored_video_stub_.reset(new MonitoredVideoStub(
          video_renderer_->GetVideoStub(),
          base::TimeDelta::FromSeconds(
              MonitoredVideoStub::kConnectivityCheckDelaySeconds),
          base::Bind(&IceConnectionToHost::OnVideoChannelStatus,
                     base::Unretained(this))));
      video_dispatcher_.reset(
          new ClientVideoDispatcher(monitored_video_stub_.get(), client_stub_));
      video_dispatcher_->Init(transport_->GetChannelFactory(), this);

      // Configure audio pipeline if necessary.
      if (session_->config().is_audio_enabled()) {
        audio_reader_.reset(new AudioReader(audio_decode_scheduler_.get()));
        audio_reader_->Init(transport_->GetMultiplexedChannelFactory(), this);
        audio_decode_scheduler_->Initialize(session_->config());
      }
      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.
      CloseChannels();
      if (state_ == CONNECTED && session_->error() == SIGNALING_TIMEOUT) {
        SetState(CLOSED, OK);
      } else {
        SetState(FAILED, session_->error());
      }
      break;
  }
}

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

void IceConnectionToHost::OnIceTransportError(ErrorCode error) {
  session_->Close(error);
}

void IceConnectionToHost::OnChannelInitialized(
    ChannelDispatcherBase* channel_dispatcher) {
  NotifyIfChannelsReady();
}

void IceConnectionToHost::OnChannelClosed(
    ChannelDispatcherBase* channel_dispatcher) {
  session_->Close(OK);
}

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

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

void IceConnectionToHost::NotifyIfChannelsReady() {
  if (!control_dispatcher_.get() || !control_dispatcher_->is_connected())
    return;
  if (!event_dispatcher_.get() || !event_dispatcher_->is_connected())
    return;
  if (!video_dispatcher_.get() || !video_dispatcher_->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 IceConnectionToHost::CloseChannels() {
  control_dispatcher_.reset();
  event_dispatcher_.reset();
  clipboard_forwarder_.set_clipboard_stub(nullptr);
  event_forwarder_.set_input_stub(nullptr);
  video_dispatcher_.reset();
  audio_reader_.reset();
}

void IceConnectionToHost::SetState(State state, ErrorCode error) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // |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
