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

#include "media/engine/payload_type_mapper.h"

#include <set>
#include <string>

#include "absl/strings/string_view.h"
#include "media/base/media_constants.h"
#include "test/gtest.h"

namespace cricket {

class PayloadTypeMapperTest : public ::testing::Test {
 protected:
  PayloadTypeMapper mapper_;
};

TEST_F(PayloadTypeMapperTest, StaticPayloadTypes) {
  EXPECT_EQ(0, mapper_.FindMappingFor({"pcmu", 8000, 1}));
  EXPECT_EQ(3, mapper_.FindMappingFor({"gsm", 8000, 1}));
  EXPECT_EQ(4, mapper_.FindMappingFor({"g723", 8000, 1}));
  EXPECT_EQ(5, mapper_.FindMappingFor({"dvi4", 8000, 1}));
  EXPECT_EQ(6, mapper_.FindMappingFor({"dvi4", 16000, 1}));
  EXPECT_EQ(7, mapper_.FindMappingFor({"lpc", 8000, 1}));
  EXPECT_EQ(8, mapper_.FindMappingFor({"pcma", 8000, 1}));
  EXPECT_EQ(9, mapper_.FindMappingFor({"g722", 8000, 1}));
  EXPECT_EQ(10, mapper_.FindMappingFor({"l16", 44100, 2}));
  EXPECT_EQ(11, mapper_.FindMappingFor({"l16", 44100, 1}));
  EXPECT_EQ(12, mapper_.FindMappingFor({"qcelp", 8000, 1}));
  EXPECT_EQ(13, mapper_.FindMappingFor({"cn", 8000, 1}));
  EXPECT_EQ(14, mapper_.FindMappingFor({"mpa", 90000, 0}));
  EXPECT_EQ(14, mapper_.FindMappingFor({"mpa", 90000, 1}));
  EXPECT_EQ(15, mapper_.FindMappingFor({"g728", 8000, 1}));
  EXPECT_EQ(16, mapper_.FindMappingFor({"dvi4", 11025, 1}));
  EXPECT_EQ(17, mapper_.FindMappingFor({"dvi4", 22050, 1}));
  EXPECT_EQ(18, mapper_.FindMappingFor({"g729", 8000, 1}));
}

TEST_F(PayloadTypeMapperTest, WebRTCPayloadTypes) {
  // Tests that the payload mapper knows about the audio formats we've
  // been using in WebRTC, with their hard coded values.
  EXPECT_EQ(102, mapper_.FindMappingFor({kIlbcCodecName, 8000, 1}));
  EXPECT_EQ(103, mapper_.FindMappingFor({kIsacCodecName, 16000, 1}));
  EXPECT_EQ(104, mapper_.FindMappingFor({kIsacCodecName, 32000, 1}));
  EXPECT_EQ(105, mapper_.FindMappingFor({kCnCodecName, 16000, 1}));
  EXPECT_EQ(106, mapper_.FindMappingFor({kCnCodecName, 32000, 1}));
  EXPECT_EQ(111, mapper_.FindMappingFor(
                     {kOpusCodecName,
                      48000,
                      2,
                      {{"minptime", "10"}, {"useinbandfec", "1"}}}));
  EXPECT_EQ(63, mapper_.FindMappingFor({kRedCodecName, 48000, 2}));
  // TODO(solenberg): Remove 16k, 32k, 48k DTMF checks once these payload types
  // are dynamically assigned.
  EXPECT_EQ(110, mapper_.FindMappingFor({kDtmfCodecName, 48000, 1}));
  EXPECT_EQ(112, mapper_.FindMappingFor({kDtmfCodecName, 32000, 1}));
  EXPECT_EQ(113, mapper_.FindMappingFor({kDtmfCodecName, 16000, 1}));
  EXPECT_EQ(126, mapper_.FindMappingFor({kDtmfCodecName, 8000, 1}));
}

TEST_F(PayloadTypeMapperTest, ValidDynamicPayloadTypes) {
  // RFC 3551 says:
  // "This profile reserves payload type numbers in the range 96-127
  // exclusively for dynamic assignment.  Applications SHOULD first use
  // values in this range for dynamic payload types.  Those applications
  // which need to define more than 32 dynamic payload types MAY bind
  // codes below 96, in which case it is RECOMMENDED that unassigned
  // payload type numbers be used first.  However, the statically assigned
  // payload types are default bindings and MAY be dynamically bound to
  // new encodings if needed."

  // Tests that the payload mapper uses values in the dynamic payload type range
  // (96 - 127) before any others and that the values returned are all valid.
  bool has_been_below_96 = false;
  std::set<int> used_payload_types;
  for (int i = 0; i != 256; ++i) {
    std::string format_name = "unknown_format_" + std::to_string(i);
    webrtc::SdpAudioFormat format(format_name.c_str(), i * 100, (i % 2) + 1);
    auto opt_payload_type = mapper_.GetMappingFor(format);
    bool mapper_is_full = false;

    // There's a limited number of slots for payload types. We're fine with not
    // being able to map them all.
    if (opt_payload_type) {
      int payload_type = *opt_payload_type;
      EXPECT_FALSE(mapper_is_full) << "Mapping should not fail sporadically";
      EXPECT_EQ(used_payload_types.find(payload_type), used_payload_types.end())
          << "Payload types must not be reused";
      used_payload_types.insert(payload_type);
      EXPECT_GE(payload_type, 0) << "Negative payload types are invalid";
      EXPECT_LE(payload_type, 127) << "Payload types above 127 are invalid";
      EXPECT_FALSE(payload_type >= 96 && has_been_below_96);
      if (payload_type < 96)
        has_been_below_96 = true;

      EXPECT_EQ(payload_type, mapper_.FindMappingFor(format))
          << "Mapping must be permanent after successful call to "
             "GetMappingFor";
      EXPECT_EQ(payload_type, mapper_.GetMappingFor(format))
          << "Subsequent calls to GetMappingFor must return the same value";
    } else {
      mapper_is_full = true;
    }
  }

  // Also, we must've been able to map at least one dynamic payload type.
  EXPECT_FALSE(used_payload_types.empty())
      << "Mapper must support at least one user-defined payload type";
}

TEST_F(PayloadTypeMapperTest, ToAudioCodec) {
  webrtc::SdpAudioFormat format("unknown_format", 4711, 17);
  auto opt_payload_type = mapper_.GetMappingFor(format);
  EXPECT_TRUE(opt_payload_type);
  auto opt_audio_codec = mapper_.ToAudioCodec(format);
  EXPECT_TRUE(opt_audio_codec);

  if (opt_payload_type && opt_audio_codec) {
    int payload_type = *opt_payload_type;
    const AudioCodec& codec = *opt_audio_codec;

    EXPECT_EQ(codec.id, payload_type);
    EXPECT_EQ(codec.name, format.name);
    EXPECT_EQ(codec.clockrate, format.clockrate_hz);
    EXPECT_EQ(codec.channels, format.num_channels);
    EXPECT_EQ(codec.params, format.parameters);
  }
}

}  // namespace cricket
