/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_API_AUDIO_CODECS_AUDIO_FORMAT_H_
#define WEBRTC_API_AUDIO_CODECS_AUDIO_FORMAT_H_

#include <map>
#include <ostream>
#include <string>
#include <utility>

#include "webrtc/base/optional.h"

namespace webrtc {

// SDP specification for a single audio codec.
// NOTE: This class is still under development and may change without notice.
struct SdpAudioFormat {
  using Parameters = std::map<std::string, std::string>;

  SdpAudioFormat(const SdpAudioFormat&);
  SdpAudioFormat(SdpAudioFormat&&);
  SdpAudioFormat(const char* name, int clockrate_hz, size_t num_channels);
  SdpAudioFormat(const std::string& name,
                 int clockrate_hz,
                 size_t num_channels);
  SdpAudioFormat(const char* name,
                 int clockrate_hz,
                 size_t num_channels,
                 const Parameters& param);
  SdpAudioFormat(const std::string& name,
                 int clockrate_hz,
                 size_t num_channels,
                 const Parameters& param);
  ~SdpAudioFormat();

  // Returns true if this format is compatible with |o|. In SDP terminology:
  // would it represent the same codec between an offer and an answer? As
  // opposed to operator==, this method disregards codec parameters.
  bool Matches(const SdpAudioFormat& o) const;

  SdpAudioFormat& operator=(const SdpAudioFormat&);
  SdpAudioFormat& operator=(SdpAudioFormat&&);

  friend bool operator==(const SdpAudioFormat& a, const SdpAudioFormat& b);
  friend bool operator!=(const SdpAudioFormat& a, const SdpAudioFormat& b) {
    return !(a == b);
  }

  std::string name;
  int clockrate_hz;
  size_t num_channels;
  Parameters parameters;
};

void swap(SdpAudioFormat& a, SdpAudioFormat& b);
std::ostream& operator<<(std::ostream& os, const SdpAudioFormat& saf);

// Information about how an audio format is treated by the codec implementation.
// Contains basic information, such as sample rate and number of channels, which
// isn't uniformly presented by SDP. Also contains flags indicating support for
// integrating with other parts of WebRTC, like external VAD and comfort noise
// level calculation.
//
// To avoid API breakage, and make the code clearer, AudioCodecInfo should not
// be directly initializable with any flags indicating optional support. If it
// were, these initializers would break any time a new flag was added. It's also
// more difficult to understand:
//   AudioCodecInfo info{16000, 1, 32000, true, false, false, true, true};
// than
//   AudioCodecInfo info(16000, 1, 32000);
//   info.allow_comfort_noise = true;
//   info.future_flag_b = true;
//   info.future_flag_c = true;
struct AudioCodecInfo {
  AudioCodecInfo(int sample_rate_hz, size_t num_channels, int bitrate_bps);
  AudioCodecInfo(int sample_rate_hz,
                 size_t num_channels,
                 int default_bitrate_bps,
                 int min_bitrate_bps,
                 int max_bitrate_bps);
  AudioCodecInfo(const AudioCodecInfo& b) = default;
  ~AudioCodecInfo() = default;

  bool operator==(const AudioCodecInfo& b) const {
    return sample_rate_hz == b.sample_rate_hz &&
           num_channels == b.num_channels &&
           default_bitrate_bps == b.default_bitrate_bps &&
           min_bitrate_bps == b.min_bitrate_bps &&
           max_bitrate_bps == b.max_bitrate_bps &&
           allow_comfort_noise == b.allow_comfort_noise &&
           supports_network_adaption == b.supports_network_adaption;
  }

  bool operator!=(const AudioCodecInfo& b) const { return !(*this == b); }

  bool HasFixedBitrate() const {
    RTC_DCHECK_GE(min_bitrate_bps, 0);
    RTC_DCHECK_LE(min_bitrate_bps, default_bitrate_bps);
    RTC_DCHECK_GE(max_bitrate_bps, default_bitrate_bps);
    return min_bitrate_bps == max_bitrate_bps;
  }

  int sample_rate_hz;
  size_t num_channels;
  int default_bitrate_bps;
  int min_bitrate_bps;
  int max_bitrate_bps;

  bool allow_comfort_noise = true;  // This codec can be used with an external
                                    // comfort noise generator.
  bool supports_network_adaption = false;  // This codec can adapt to varying
                                           // network conditions.
};

// AudioCodecSpec ties an audio format to specific information about the codec
// and its implementation.
struct AudioCodecSpec {
  bool operator==(const AudioCodecSpec& b) const {
    return format == b.format && info == b.info;
  }

  bool operator!=(const AudioCodecSpec& b) const { return !(*this == b); }

  SdpAudioFormat format;
  AudioCodecInfo info;
};

}  // namespace webrtc

#endif  // WEBRTC_API_AUDIO_CODECS_AUDIO_FORMAT_H_
