/*
 *  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 "modules/rtp_rtcp/source/rtcp_packet/remb.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <vector>

#include "rtc_base/buffer.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/rtcp_packet_parser.h"

using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
using ::testing::make_tuple;
using webrtc::rtcp::Remb;

namespace webrtc {
namespace {
const uint32_t kSenderSsrc = 0x12345678;
const uint32_t kRemoteSsrcs[] = {0x23456789, 0x2345678a, 0x2345678b};
const uint32_t kBitrateBps = 0x3fb93 * 2;  // 522022;
const int64_t kBitrateBps64bit = int64_t{0x3fb93} << 30;
const uint8_t kPacket[] = {0x8f, 206,  0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
                           0x00, 0x00, 0x00, 0x00, 'R',  'E',  'M',  'B',
                           0x03, 0x07, 0xfb, 0x93, 0x23, 0x45, 0x67, 0x89,
                           0x23, 0x45, 0x67, 0x8a, 0x23, 0x45, 0x67, 0x8b};
const size_t kPacketLength = sizeof(kPacket);
}  // namespace

TEST(RtcpPacketRembTest, Create) {
  Remb remb;
  remb.SetSenderSsrc(kSenderSsrc);
  remb.SetSsrcs(
      std::vector<uint32_t>(std::begin(kRemoteSsrcs), std::end(kRemoteSsrcs)));
  remb.SetBitrateBps(kBitrateBps);

  Buffer packet = remb.Build();

  EXPECT_THAT(make_tuple(packet.data(), packet.size()),
              ElementsAreArray(kPacket));
}

TEST(RtcpPacketRembTest, Parse) {
  Remb remb;
  EXPECT_TRUE(test::ParseSinglePacket(kPacket, &remb));
  const Remb& parsed = remb;

  EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
  EXPECT_EQ(kBitrateBps, parsed.bitrate_bps());
  EXPECT_THAT(parsed.ssrcs(), ElementsAreArray(kRemoteSsrcs));
}

TEST(RtcpPacketRembTest, CreateAndParseWithoutSsrcs) {
  Remb remb;
  remb.SetSenderSsrc(kSenderSsrc);
  remb.SetBitrateBps(kBitrateBps);
  Buffer packet = remb.Build();

  Remb parsed;
  EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
  EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
  EXPECT_EQ(kBitrateBps, parsed.bitrate_bps());
  EXPECT_THAT(parsed.ssrcs(), IsEmpty());
}

TEST(RtcpPacketRembTest, CreateAndParse64bitBitrate) {
  Remb remb;
  remb.SetBitrateBps(kBitrateBps64bit);
  Buffer packet = remb.Build();

  Remb parsed;
  EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
  EXPECT_EQ(kBitrateBps64bit, parsed.bitrate_bps());
}

TEST(RtcpPacketRembTest, ParseFailsOnTooSmallPacketToBeRemb) {
  // Make it too small.
  constexpr size_t kTooSmallSize = (1 + 3) * 4;
  uint8_t packet[kTooSmallSize];
  memcpy(packet, kPacket, kTooSmallSize);
  packet[3] = 3;

  Remb remb;
  EXPECT_FALSE(test::ParseSinglePacket(packet, &remb));
}

TEST(RtcpPacketRembTest, ParseFailsWhenUniqueIdentifierIsNotRemb) {
  uint8_t packet[kPacketLength];
  memcpy(packet, kPacket, kPacketLength);
  packet[12] = 'N';  // Swap 'R' -> 'N' in the 'REMB' unique identifier.

  Remb remb;
  EXPECT_FALSE(test::ParseSinglePacket(packet, &remb));
}

TEST(RtcpPacketRembTest, ParseFailsWhenBitrateDoNotFitIn64bits) {
  uint8_t packet[kPacketLength];
  memcpy(packet, kPacket, kPacketLength);
  packet[17] |= 0xfc;  // Set exponent component to maximum of 63.
  packet[19] |= 0x02;  // Ensure mantissa is at least 2.

  Remb remb;
  EXPECT_FALSE(test::ParseSinglePacket(packet, &remb));
}

TEST(RtcpPacketRembTest, ParseFailsWhenBitrateDoNotFitIn63bits) {
  uint8_t packet[kPacketLength];
  memcpy(packet, kPacket, kPacketLength);
  packet[17] = 56 << 2;  // Set exponent component to 56.
  packet[18] = 0;        // Set mantissa to 200 > 128
  packet[19] = 200;

  // Result value 200 * 2^56 can't be represented with int64_t and thus should
  // be rejected.
  Remb remb;
  EXPECT_FALSE(test::ParseSinglePacket(packet, &remb));
}

TEST(RtcpPacketRembTest, ParseFailsWhenSsrcCountMismatchLength) {
  uint8_t packet[kPacketLength];
  memcpy(packet, kPacket, kPacketLength);
  packet[16]++;  // Swap 3 -> 4 in the ssrcs count.

  Remb remb;
  EXPECT_FALSE(test::ParseSinglePacket(packet, &remb));
}

TEST(RtcpPacketRembTest, TooManySsrcs) {
  Remb remb;
  EXPECT_FALSE(remb.SetSsrcs(
      std::vector<uint32_t>(Remb::kMaxNumberOfSsrcs + 1, kRemoteSsrcs[0])));
  EXPECT_TRUE(remb.SetSsrcs(
      std::vector<uint32_t>(Remb::kMaxNumberOfSsrcs, kRemoteSsrcs[0])));
}

}  // namespace webrtc
