/*
 *  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, {{"", "111/111"}}}));
  // 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
