/*
 *  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 "webrtc/test/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
