// 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.

#ifndef REMOTING_PROTOCOL_SESSION_CONFIG_H_
#define REMOTING_PROTOCOL_SESSION_CONFIG_H_

#include <list>
#include <memory>
#include <string>


namespace remoting {
namespace protocol {

extern const int kDefaultStreamVersion;

// Struct for configuration parameters of a single channel.
// Some channels (like video) may have multiple underlying sockets that need
// to be configured simultaneously.
struct ChannelConfig {
  enum TransportType {
    TRANSPORT_STREAM,
    TRANSPORT_MUX_STREAM,
    TRANSPORT_DATAGRAM,
    TRANSPORT_NONE,
  };

  enum Codec {
    CODEC_UNDEFINED,  // Used for event and control channels.
    CODEC_VERBATIM,
    CODEC_ZIP,
    CODEC_VP8,
    CODEC_VP9,
    CODEC_H264,
    CODEC_OPUS,
    CODEC_SPEEX,
  };

  // Creates a config with transport field set to TRANSPORT_NONE which indicates
  // that corresponding channel is disabled.
  static ChannelConfig None();

  // Default constructor. Equivalent to None().
  ChannelConfig() = default;

  // Creates a channel config with the specified parameters.
  ChannelConfig(TransportType transport, int version, Codec codec);

  // operator== is overloaded so that std::find() works with
  // std::list<ChannelConfig>.
  bool operator==(const ChannelConfig& b) const;

  TransportType transport = TRANSPORT_NONE;
  int version = 0;
  Codec codec = CODEC_UNDEFINED;
};

class CandidateSessionConfig;

// SessionConfig is used to represent negotiated session configuration. Note
// that it's useful mainly for the legacy protocol. When using the new
// WebRTC-based protocol the using_webrtc() flag is set to true and all other
// fields should be ignored.
class SessionConfig {
 public:
  enum class Protocol {
    // Current ICE-based protocol.
    ICE,

    // New WebRTC-based protocol.
    WEBRTC,
  };

  // Selects session configuration that is supported by both participants.
  // nullptr is returned if such configuration doesn't exist. When selecting
  // channel configuration priority is given to the configs listed first
  // in |client_config|.
  static std::unique_ptr<SessionConfig> SelectCommon(
      const CandidateSessionConfig* client_config,
      const CandidateSessionConfig* host_config);

  // Extracts final protocol configuration. Must be used for the description
  // received in the session-accept stanza. If the selection is ambiguous
  // (e.g. there is more than one configuration for one of the channel)
  // or undefined (e.g. no configurations for a channel) then nullptr is
  // returned.
  static std::unique_ptr<SessionConfig> GetFinalConfig(
      const CandidateSessionConfig* candidate_config);

  // Returns a suitable session configuration for use in tests.
  static std::unique_ptr<SessionConfig> ForTest();
  static std::unique_ptr<SessionConfig> ForTestWithAudio();
  static std::unique_ptr<SessionConfig> ForTestWithVerbatimVideo();
  static std::unique_ptr<SessionConfig> ForTestWithWebrtc();

  Protocol protocol() const { return protocol_; }

  // All fields below should be ignored when protocol() is set to WEBRTC.
  const ChannelConfig& control_config() const;
  const ChannelConfig& event_config() const;
  const ChannelConfig& video_config() const;
  const ChannelConfig& audio_config() const;

  bool is_audio_enabled() const {
    return audio_config_.transport != ChannelConfig::TRANSPORT_NONE;
  }

 private:
  SessionConfig(Protocol protocol);

  const Protocol protocol_;

  ChannelConfig control_config_;
  ChannelConfig event_config_;
  ChannelConfig video_config_;
  ChannelConfig audio_config_;
};

// Defines session description that is sent from client to the host in the
// session-initiate message. It is different from the regular Config
// because it allows one to specify multiple configurations for each channel.
class CandidateSessionConfig {
 public:
  static std::unique_ptr<CandidateSessionConfig> CreateEmpty();
  static std::unique_ptr<CandidateSessionConfig> CreateFrom(
      const SessionConfig& config);
  static std::unique_ptr<CandidateSessionConfig> CreateDefault();

  ~CandidateSessionConfig();

  bool webrtc_supported() const { return webrtc_supported_; }
  void set_webrtc_supported(bool webrtc_supported) {
    webrtc_supported_ = webrtc_supported;
  }

  bool ice_supported() const { return ice_supported_; }
  void set_ice_supported(bool ice_supported) { ice_supported_ = ice_supported; }

  const std::list<ChannelConfig>& control_configs() const {
    return control_configs_;
  }

  std::list<ChannelConfig>* mutable_control_configs() {
    return &control_configs_;
  }

  const std::list<ChannelConfig>& event_configs() const {
    return event_configs_;
  }

  std::list<ChannelConfig>* mutable_event_configs() {
    return &event_configs_;
  }

  const std::list<ChannelConfig>& video_configs() const {
    return video_configs_;
  }

  std::list<ChannelConfig>* mutable_video_configs() {
    return &video_configs_;
  }

  const std::list<ChannelConfig>& audio_configs() const {
    return audio_configs_;
  }

  std::list<ChannelConfig>* mutable_audio_configs() {
    return &audio_configs_;
  }

  // Old clients always list VP9 as supported and preferred even though they
  // shouldn't have it enabled yet. I.e. the host cannot trust VP9 codec
  // preference received from the client. To workaround this issue the client
  // adds a hint in the session-initiate message to indicate that it actually
  // wants VP9 to be enabled.
  //
  // TODO(sergeyu): Remove this kludge as soon as VP9 is enabled by default.
  bool vp9_experiment_enabled() const { return vp9_experiment_enabled_; }
  void set_vp9_experiment_enabled(bool value) {
    vp9_experiment_enabled_ = value;
  }

  bool h264_experiment_enabled() const { return h264_experiment_enabled_; }
  void set_h264_experiment_enabled(bool value) {
    h264_experiment_enabled_ = value;
  }

  // Returns true if |config| is supported.
  bool IsSupported(const SessionConfig& config) const;

  std::unique_ptr<CandidateSessionConfig> Clone() const;

  // Helpers for enabling/disabling specific features.
  void DisableAudioChannel();
  void PreferTransport(ChannelConfig::TransportType transport);

 private:
  CandidateSessionConfig();
  explicit CandidateSessionConfig(const CandidateSessionConfig& config);
  CandidateSessionConfig& operator=(const CandidateSessionConfig& b);

  bool webrtc_supported_ = false;
  bool ice_supported_ = false;

  std::list<ChannelConfig> control_configs_;
  std::list<ChannelConfig> event_configs_;
  std::list<ChannelConfig> video_configs_;
  std::list<ChannelConfig> audio_configs_;

  bool vp9_experiment_enabled_ = false;
  bool h264_experiment_enabled_ = false;
};

}  // namespace protocol
}  // namespace remoting

#endif  // REMOTING_PROTOCOL_SESSION_CONFIG_H_
