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

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/memory/ptr_util.h"

namespace remoting {
namespace protocol {

namespace {

bool IsChannelConfigSupported(const std::list<ChannelConfig>& list,
                              const ChannelConfig& value) {
  return std::find(list.begin(), list.end(), value) != list.end();
}

bool SelectCommonChannelConfig(const std::list<ChannelConfig>& host_configs,
                               const std::list<ChannelConfig>& client_configs,
                               ChannelConfig* config) {
  // Usually each of these lists will contain just a few elements, so iterating
  // over all of them is not a problem.
  std::list<ChannelConfig>::const_iterator it;
  for (it = client_configs.begin(); it != client_configs.end(); ++it) {
    if (IsChannelConfigSupported(host_configs, *it)) {
      *config = *it;
      return true;
    }
  }
  return false;
}

void UpdateConfigListToPreferTransport(std::list<ChannelConfig>* configs,
                                       ChannelConfig::TransportType transport) {
  std::vector<ChannelConfig> sorted(configs->begin(), configs->end());
  std::stable_sort(sorted.begin(), sorted.end(),
                   [transport](const ChannelConfig& a, const ChannelConfig& b) {
                     // |a| must precede |b| if |a| uses preferred transport and
                     // |b| doesn't.
                     return a.transport == transport &&
                            b.transport != transport;
                   });
  configs->assign(sorted.begin(), sorted.end());
}

}  // namespace

const int kDefaultStreamVersion = 2;
const int kControlStreamVersion = 3;

ChannelConfig ChannelConfig::None() {
  return ChannelConfig();
}

ChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec)
    : transport(transport),
      version(version),
      codec(codec) {
}

bool ChannelConfig::operator==(const ChannelConfig& b) const {
  // If the transport field is set to NONE then all other fields are irrelevant.
  if (transport == ChannelConfig::TRANSPORT_NONE)
    return transport == b.transport;
  return transport == b.transport && version == b.version && codec == b.codec;
}

// static
std::unique_ptr<SessionConfig> SessionConfig::SelectCommon(
    const CandidateSessionConfig* client_config,
    const CandidateSessionConfig* host_config) {
  // Use WebRTC if both host and client support it.
  if (client_config->webrtc_supported() && host_config->webrtc_supported())
    return base::WrapUnique(new SessionConfig(Protocol::WEBRTC));

  // Reject connection if ICE is not supported by either of the peers.
  if (!host_config->ice_supported() || !client_config->ice_supported())
    return nullptr;

  std::unique_ptr<SessionConfig> result(new SessionConfig(Protocol::ICE));

  // If neither host nor the client have VP9 experiment enabled then remove it
  // from the list of host video configs.
  std::list<ChannelConfig> host_video_configs = host_config->video_configs();
  if (!client_config->vp9_experiment_enabled() &&
      !host_config->vp9_experiment_enabled()) {
    host_video_configs.remove_if([](const ChannelConfig& config) {
      return config.codec == ChannelConfig::CODEC_VP9;
    });
  }

  // If neither host nor the client have H264 experiment enabled then remove it
  // from the list of host video configs.
  if (!client_config->h264_experiment_enabled() &&
      !host_config->h264_experiment_enabled()) {
    host_video_configs.remove_if([](const ChannelConfig& config) {
      return config.codec == ChannelConfig::CODEC_H264;
    });
  }

  if (!SelectCommonChannelConfig(host_config->control_configs(),
                                 client_config->control_configs(),
                                 &result->control_config_) ||
      !SelectCommonChannelConfig(host_config->event_configs(),
                                 client_config->event_configs(),
                                 &result->event_config_) ||
      !SelectCommonChannelConfig(host_video_configs,
                                 client_config->video_configs(),
                                 &result->video_config_) ||
      !SelectCommonChannelConfig(host_config->audio_configs(),
                                 client_config->audio_configs(),
                                 &result->audio_config_)) {
    return nullptr;
  }

  return result;
}

// static
std::unique_ptr<SessionConfig> SessionConfig::GetFinalConfig(
    const CandidateSessionConfig* candidate_config) {
  if (candidate_config->webrtc_supported()) {
    if (candidate_config->ice_supported()) {
      LOG(ERROR) << "Received candidate config is ambiguous.";
      return nullptr;
    }
    return base::WrapUnique(new SessionConfig(Protocol::WEBRTC));
  }

  if (!candidate_config->ice_supported())
    return nullptr;

  if (candidate_config->control_configs().size() != 1 ||
      candidate_config->event_configs().size() != 1 ||
      candidate_config->video_configs().size() != 1 ||
      candidate_config->audio_configs().size() != 1) {
    return nullptr;
  }

  std::unique_ptr<SessionConfig> result(new SessionConfig(Protocol::ICE));
  result->control_config_ = candidate_config->control_configs().front();
  result->event_config_ = candidate_config->event_configs().front();
  result->video_config_ = candidate_config->video_configs().front();
  result->audio_config_ = candidate_config->audio_configs().front();

  return result;
}

// static
std::unique_ptr<SessionConfig> SessionConfig::ForTest() {
  std::unique_ptr<SessionConfig> result(new SessionConfig(Protocol::ICE));
  result->control_config_ =
      ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, kControlStreamVersion,
                    ChannelConfig::CODEC_UNDEFINED);
  result->event_config_ =
      ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, kDefaultStreamVersion,
                    ChannelConfig::CODEC_UNDEFINED);
  result->video_config_ =
      ChannelConfig(ChannelConfig::TRANSPORT_STREAM, kDefaultStreamVersion,
                    ChannelConfig::CODEC_VP8);
  result->audio_config_ =
      ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, kDefaultStreamVersion,
                    ChannelConfig::CODEC_OPUS);
  return result;
}

std::unique_ptr<SessionConfig> SessionConfig::ForTestWithAudio() {
  std::unique_ptr<SessionConfig> result(ForTest());
  result->audio_config_ = ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
                                        kDefaultStreamVersion,
                                        ChannelConfig::CODEC_OPUS);
  return result;
}

std::unique_ptr<SessionConfig> SessionConfig::ForTestWithVerbatimVideo() {
  std::unique_ptr<SessionConfig> result = ForTest();
  result->video_config_ = ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
                                        kDefaultStreamVersion,
                                        ChannelConfig::CODEC_VERBATIM);
  return result;
}

std::unique_ptr<SessionConfig> SessionConfig::ForTestWithWebrtc() {
  return base::WrapUnique(new SessionConfig(Protocol::WEBRTC));
}

const ChannelConfig& SessionConfig::control_config() const {
  DCHECK(protocol_ == Protocol::ICE);
  return control_config_;
}
const ChannelConfig& SessionConfig::event_config() const {
  DCHECK(protocol_ == Protocol::ICE);
  return event_config_;
}
const ChannelConfig& SessionConfig::video_config() const {
  DCHECK(protocol_ == Protocol::ICE);
  return video_config_;
}
const ChannelConfig& SessionConfig::audio_config() const {
  DCHECK(protocol_ == Protocol::ICE);
  return audio_config_;
}

SessionConfig::SessionConfig(Protocol protocol) : protocol_(protocol) {}

CandidateSessionConfig::CandidateSessionConfig() = default;
CandidateSessionConfig::CandidateSessionConfig(
    const CandidateSessionConfig& config) = default;
CandidateSessionConfig::~CandidateSessionConfig() = default;

bool CandidateSessionConfig::IsSupported(const SessionConfig& config) const {
  switch (config.protocol()) {
    case SessionConfig::Protocol::ICE:
      return ice_supported() &&
             IsChannelConfigSupported(control_configs_,
                                      config.control_config()) &&
             IsChannelConfigSupported(event_configs_, config.event_config()) &&
             IsChannelConfigSupported(video_configs_, config.video_config()) &&
             IsChannelConfigSupported(audio_configs_, config.audio_config());

    case SessionConfig::Protocol::WEBRTC:
      return webrtc_supported();
  }

  NOTREACHED();
  return false;
}

std::unique_ptr<CandidateSessionConfig> CandidateSessionConfig::Clone() const {
  return base::WrapUnique(new CandidateSessionConfig(*this));
}

// static
std::unique_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateEmpty() {
  return base::WrapUnique(new CandidateSessionConfig());
}

// static
std::unique_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateFrom(
    const SessionConfig& config) {
  std::unique_ptr<CandidateSessionConfig> result = CreateEmpty();

  switch (config.protocol()) {
    case SessionConfig::Protocol::WEBRTC:
      result->set_webrtc_supported(true);
      result->set_ice_supported(false);
      break;

    case SessionConfig::Protocol::ICE:
      result->set_webrtc_supported(false);
      result->set_ice_supported(true);
      result->mutable_control_configs()->push_back(config.control_config());
      result->mutable_event_configs()->push_back(config.event_config());
      result->mutable_video_configs()->push_back(config.video_config());
      result->mutable_audio_configs()->push_back(config.audio_config());
      break;
  }

  return result;
}

// static
std::unique_ptr<CandidateSessionConfig>
CandidateSessionConfig::CreateDefault() {
  std::unique_ptr<CandidateSessionConfig> result = CreateEmpty();

  result->set_ice_supported(true);

  // Control channel.
  result->mutable_control_configs()->push_back(
      ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
                    kControlStreamVersion,
                    ChannelConfig::CODEC_UNDEFINED));

  // Event channel.
  result->mutable_event_configs()->push_back(
      ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
                    kDefaultStreamVersion,
                    ChannelConfig::CODEC_UNDEFINED));

  // Video channel.
  result->mutable_video_configs()->push_back(
      ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
                    kDefaultStreamVersion,
                    ChannelConfig::CODEC_VP9));
  result->mutable_video_configs()->push_back(
      ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
                    kDefaultStreamVersion,
                    ChannelConfig::CODEC_VP8));

  // Audio channel.
  result->mutable_audio_configs()->push_back(
      ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
                    kDefaultStreamVersion,
                    ChannelConfig::CODEC_OPUS));
  result->mutable_audio_configs()->push_back(ChannelConfig::None());

  return result;
}

void CandidateSessionConfig::DisableAudioChannel() {
  mutable_audio_configs()->clear();
  mutable_audio_configs()->push_back(ChannelConfig());
}

void CandidateSessionConfig::PreferTransport(
    ChannelConfig::TransportType transport) {
  UpdateConfigListToPreferTransport(&control_configs_, transport);
  UpdateConfigListToPreferTransport(&event_configs_, transport);
  UpdateConfigListToPreferTransport(&video_configs_, transport);
  UpdateConfigListToPreferTransport(&audio_configs_, transport);
}

}  // namespace protocol
}  // namespace remoting
