/*
 *  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::kAutoGainControl[] = "googAutoGainControl";
const char MediaConstraints::kNoiseSuppression[] = "googNoiseSuppression";
const char MediaConstraints::kHighpassFilter[] = "googHighpassFilter";
const char MediaConstraints::kAudioMirroring[] = "googAudioMirroring";
const char MediaConstraints::kAudioNetworkAdaptorConfig[] =
    "googAudioNetworkAdaptorConfig";
const char MediaConstraints::kInitAudioRecordingOnSend[] =
    "InitAudioRecordingOnSend";

// 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.
// 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);
  // 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);
}

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

  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kGoogEchoCancellation,
                             &options->echo_cancellation);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kAutoGainControl,
                             &options->auto_gain_control);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kNoiseSuppression,
                             &options->noise_suppression);
  ConstraintToOptional<bool>(constraints, MediaConstraints::kHighpassFilter,
                             &options->highpass_filter);
  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;
  }
  ConstraintToOptional<bool>(constraints,
                             MediaConstraints::kInitAudioRecordingOnSend,
                             &options->init_recording_on_send);
}

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
