/*
 *  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 <set>
#include <string>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/media/engine/payload_type_mapper.h"

namespace cricket {

class PayloadTypeMapperTest : public testing::Test {
 public:
  // TODO(ossu): These are to work around missing comparison operators in
  // rtc::Optional. They should be removed once Optional has been updated.
  int FindMapping(const webrtc::SdpAudioFormat& format) {
    auto opt_mapping = mapper_.FindMappingFor(format);
    if (opt_mapping)
      return *opt_mapping;
    return -1;
  }

  int GetMapping(const webrtc::SdpAudioFormat& format) {
    auto opt_mapping = mapper_.GetMappingFor(format);
    if (opt_mapping)
      return *opt_mapping;
    return -1;
  }

 protected:
  PayloadTypeMapper mapper_;
};

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

TEST_F(PayloadTypeMapperTest, WebRTCPayloadTypes) {
  // Tests that the payload mapper knows about the formats we've been using in
  // WebRTC, with their hard coded values.
  auto video_mapping = [this] (const char *name) {
    return FindMapping({name, kVideoCodecClockrate, 0});
  };
  EXPECT_EQ(kDefaultVp8PlType,  video_mapping(kVp8CodecName));
  EXPECT_EQ(kDefaultVp9PlType,  video_mapping(kVp9CodecName));
  EXPECT_EQ(kDefaultH264PlType, video_mapping(kH264CodecName));
  EXPECT_EQ(kDefaultRedPlType,  video_mapping(kRedCodecName));
  EXPECT_EQ(kDefaultUlpfecType, video_mapping(kUlpfecCodecName));

  auto rtx_mapping = [this] (int payload_type) {
    return FindMapping({kRtxCodecName, kVideoCodecClockrate, 0,
        {{ kCodecParamAssociatedPayloadType, std::to_string(payload_type)}}});
  };
  EXPECT_EQ(kDefaultRtxVp8PlType,  rtx_mapping(kDefaultVp8PlType));
  EXPECT_EQ(kDefaultRtxVp9PlType,  rtx_mapping(kDefaultVp9PlType));
  EXPECT_EQ(kDefaultRtxH264PlType, rtx_mapping(kDefaultH264PlType));
  EXPECT_EQ(kDefaultRtxRedPlType,  rtx_mapping(kDefaultRedPlType));

  EXPECT_EQ(102, FindMapping({kIlbcCodecName,  8000, 1}));
  EXPECT_EQ(103, FindMapping({kIsacCodecName, 16000, 1}));
  EXPECT_EQ(104, FindMapping({kIsacCodecName, 32000, 1}));
  EXPECT_EQ(105, FindMapping({kCnCodecName,   16000, 1}));
  EXPECT_EQ(106, FindMapping({kCnCodecName,   32000, 1}));
  EXPECT_EQ(111, FindMapping({kOpusCodecName, 48000, 2,
        {{"minptime", "10"}, {"useinbandfec", "1"}}}));
  EXPECT_EQ(126, FindMapping({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, FindMapping(format))
          << "Mapping must be permanent after successful call to "
             "GetMappingFor";
      EXPECT_EQ(payload_type, GetMapping(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
