/*
 *  Copyright 2013 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.
 */

#include "sdk/media_constraints.h"

#include "absl/types/optional.h"
#include "api/peer_connection_interface.h"

namespace webrtc {
namespace {

// Find the highest-priority instance of the T-valued constraint named by
// |key| and return its value as |value|. |constraints| can be null.
// If |mandatory_constraints| is non-null, it is incremented if the key appears
// among the mandatory constraints.
// Returns true if the key was found and has a valid value for type T.
// If the key appears multiple times as an optional constraint, appearances
// after the first are ignored.
// Note: Because this uses FindFirst, repeated optional constraints whose
// first instance has an unrecognized value are not handled precisely in
// accordance with the specification.
template <typename T>
bool FindConstraint(const MediaConstraints* constraints,
                    const std::string& key,
                    T* value,
                    size_t* mandatory_constraints) {
  std::string string_value;
  if (!FindConstraint(constraints, key, &string_value, mandatory_constraints)) {
    return false;
  }
  return rtc::FromString(string_value, value);
}

// Specialization for std::string, since a string doesn't need conversion.
template <>
bool FindConstraint(const MediaConstraints* constraints,
                    const std::string& key,
                    std::string* value,
                    size_t* mandatory_constraints) {
  if (!constraints) {
    return false;
  }
  if (constraints->GetMandatory().FindFirst(key, value)) {
    if (mandatory_constraints) {
      ++*mandatory_constraints;
    }
    return true;
  }
  if (constraints->GetOptional().FindFirst(key, value)) {
    return true;
  }
  return false;
}

bool FindConstraint(const MediaConstraints* constraints,
                    const std::string& key,
                    bool* value,
                    size_t* mandatory_constraints) {
  return FindConstraint<bool>(constraints, key, value, mandatory_constraints);
}

bool FindConstraint(const MediaConstraints* constraints,
                    const std::string& key,
                    int* value,
                    size_t* mandatory_constraints) {
  return FindConstraint<int>(constraints, key, value, mandatory_constraints);
}

// Converts a constraint (mandatory takes precedence over optional) to an
// absl::optional.
template <typename T>
void ConstraintToOptional(const MediaConstraints* constraints,
                          const std::string& key,
                          absl::optional<T>* value_out) {
  T value;
  bool present = FindConstraint<T>(constraints, key, &value, nullptr);
  if (present) {
    *value_out = value;
  }
}
}  // namespace

const char MediaConstraints::kValueTrue[] = "true";
const char MediaConstraints::kValueFalse[] = "false";

// Constraints declared as static members in mediastreaminterface.h

// Audio constraints.
const char MediaConstraints::kGoogEchoCancellation[] = "googEchoCancellation";
const char MediaConstraints::kExtendedFilterEchoCancellation[] =
    "googEchoCancellation2";
const char MediaConstraints::kDAEchoCancellation[] = "googDAEchoCancellation";
const char MediaConstraints::kAutoGainControl[] = "googAutoGainControl";
const char MediaConstraints::kExperimentalAutoGainControl[] =
    "googAutoGainControl2";
const char MediaConstraints::kNoiseSuppression[] = "googNoiseSuppression";
const char MediaConstraints::kExperimentalNoiseSuppression[] =
    "googNoiseSuppression2";
const char MediaConstraints::kHighpassFilter[] = "googHighpassFilter";
const char MediaConstraints::kTypingNoiseDetection[] =
    "googTypingNoiseDetection";
const char MediaConstraints::kAudioMirroring[] = "googAudioMirroring";
const char MediaConstraints::kAudioNetworkAdaptorConfig[] =
    "googAudioNetworkAdaptorConfig";

// Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
const char MediaConstraints::kOfferToReceiveAudio[] = "OfferToReceiveAudio";
const char MediaConstraints::kOfferToReceiveVideo[] = "OfferToReceiveVideo";
const char MediaConstraints::kVoiceActivityDetection[] =
    "VoiceActivityDetection";
const char MediaConstraints::kIceRestart[] = "IceRestart";
// Google specific constraint for BUNDLE enable/disable.
const char MediaConstraints::kUseRtpMux[] = "googUseRtpMUX";

// Below constraints should be used during PeerConnection construction.
const char MediaConstraints::kEnableDtlsSrtp[] = "DtlsSrtpKeyAgreement";
const char MediaConstraints::kEnableRtpDataChannels[] = "RtpDataChannels";
// Google-specific constraint keys.
const char MediaConstraints::kEnableDscp[] = "googDscp";
const char MediaConstraints::kEnableIPv6[] = "googIPv6";
const char MediaConstraints::kEnableVideoSuspendBelowMinBitrate[] =
    "googSuspendBelowMinBitrate";
const char MediaConstraints::kCombinedAudioVideoBwe[] =
    "googCombinedAudioVideoBwe";
const char MediaConstraints::kScreencastMinBitrate[] =
    "googScreencastMinBitrate";
// TODO(ronghuawu): Remove once cpu overuse detection is stable.
const char MediaConstraints::kCpuOveruseDetection[] = "googCpuOveruseDetection";

const char MediaConstraints::kRawPacketizationForVideoEnabled[] =
    "googRawPacketizationForVideoEnabled";

const char MediaConstraints::kNumSimulcastLayers[] = "googNumSimulcastLayers";

// Set |value| to the value associated with the first appearance of |key|, or
// return false if |key| is not found.
bool MediaConstraints::Constraints::FindFirst(const std::string& key,
                                              std::string* value) const {
  for (Constraints::const_iterator iter = begin(); iter != end(); ++iter) {
    if (iter->key == key) {
      *value = iter->value;
      return true;
    }
  }
  return false;
}

void CopyConstraintsIntoRtcConfiguration(
    const MediaConstraints* constraints,
    PeerConnectionInterface::RTCConfiguration* configuration) {
  // Copy info from constraints into configuration, if present.
  if (!constraints) {
    return;
  }

  bool enable_ipv6;
  if (FindConstraint(constraints, MediaConstraints::kEnableIPv6, &enable_ipv6,
                     nullptr)) {
    configuration->disable_ipv6 = !enable_ipv6;
  }
  FindConstraint(constraints, MediaConstraints::kEnableDscp,
                 &configuration->media_config.enable_dscp, nullptr);
  FindConstraint(constraints, MediaConstraints::kCpuOveruseDetection,
                 &configuration->media_config.video.enable_cpu_adaptation,
                 nullptr);
  FindConstraint(constraints, MediaConstraints::kEnableRtpDataChannels,
                 &configuration->enable_rtp_data_channel, nullptr);
  // Find Suspend Below Min Bitrate constraint.
  FindConstraint(
      constraints, MediaConstraints::kEnableVideoSuspendBelowMinBitrate,
      &configuration->media_config.video.suspend_below_min_bitrate, nullptr);
  ConstraintToOptional<int>(constraints,
                            MediaConstraints::kScreencastMinBitrate,
                            &configuration->screencast_min_bitrate);
  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kCombinedAudioVideoBwe,
                             &configuration->combined_audio_video_bwe);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kEnableDtlsSrtp,
                             &configuration->enable_dtls_srtp);
}

void CopyConstraintsIntoAudioOptions(const MediaConstraints* constraints,
                                     cricket::AudioOptions* options) {
  if (!constraints) {
    return;
  }

  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kGoogEchoCancellation,
                             &options->echo_cancellation);
  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kExtendedFilterEchoCancellation,
                             &options->extended_filter_aec);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kDAEchoCancellation,
                             &options->delay_agnostic_aec);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kAutoGainControl,
                             &options->auto_gain_control);
  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kExperimentalAutoGainControl,
                             &options->experimental_agc);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kNoiseSuppression,
                             &options->noise_suppression);
  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kExperimentalNoiseSuppression,
                             &options->experimental_ns);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kHighpassFilter,
                             &options->highpass_filter);
  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kTypingNoiseDetection,
                             &options->typing_detection);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kAudioMirroring,
                             &options->stereo_swapping);
  ConstraintToOptional<std::string>(
      constraints, MediaConstraints::kAudioNetworkAdaptorConfig,
      &options->audio_network_adaptor_config);
  // When |kAudioNetworkAdaptorConfig| is defined, it both means that audio
  // network adaptor is desired, and provides the config string.
  if (options->audio_network_adaptor_config) {
    options->audio_network_adaptor = true;
  }
}

bool CopyConstraintsIntoOfferAnswerOptions(
    const MediaConstraints* constraints,
    PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) {
  if (!constraints) {
    return true;
  }

  bool value = false;
  size_t mandatory_constraints_satisfied = 0;

  if (FindConstraint(constraints, MediaConstraints::kOfferToReceiveAudio,
                     &value, &mandatory_constraints_satisfied)) {
    offer_answer_options->offer_to_receive_audio =
        value ? PeerConnectionInterface::RTCOfferAnswerOptions::
                    kOfferToReceiveMediaTrue
              : 0;
  }

  if (FindConstraint(constraints, MediaConstraints::kOfferToReceiveVideo,
                     &value, &mandatory_constraints_satisfied)) {
    offer_answer_options->offer_to_receive_video =
        value ? PeerConnectionInterface::RTCOfferAnswerOptions::
                    kOfferToReceiveMediaTrue
              : 0;
  }
  if (FindConstraint(constraints, MediaConstraints::kVoiceActivityDetection,
                     &value, &mandatory_constraints_satisfied)) {
    offer_answer_options->voice_activity_detection = value;
  }
  if (FindConstraint(constraints, MediaConstraints::kUseRtpMux, &value,
                     &mandatory_constraints_satisfied)) {
    offer_answer_options->use_rtp_mux = value;
  }
  if (FindConstraint(constraints, MediaConstraints::kIceRestart, &value,
                     &mandatory_constraints_satisfied)) {
    offer_answer_options->ice_restart = value;
  }

  if (FindConstraint(constraints,
                     MediaConstraints::kRawPacketizationForVideoEnabled, &value,
                     &mandatory_constraints_satisfied)) {
    offer_answer_options->raw_packetization_for_video = value;
  }

  int layers;
  if (FindConstraint(constraints, MediaConstraints::kNumSimulcastLayers,
                     &layers, &mandatory_constraints_satisfied)) {
    offer_answer_options->num_simulcast_layers = layers;
  }

  return mandatory_constraints_satisfied == constraints->GetMandatory().size();
}

}  // namespace webrtc
