/*
 *  Copyright (c) 2017 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/rtp_format_video_generic.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <vector>

#include "api/array_view.h"
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::Contains;
using ::testing::Each;
using ::testing::ElementsAreArray;
using ::testing::Le;
using ::testing::SizeIs;

constexpr RtpPacketizer::PayloadSizeLimits kNoSizeLimits;

std::vector<int> NextPacketFillPayloadSizes(RtpPacketizerGeneric* packetizer) {
  RtpPacketToSend packet(nullptr);
  std::vector<int> result;
  while (packetizer->NextPacket(&packet)) {
    result.push_back(packet.payload_size());
  }
  return result;
}

TEST(RtpPacketizerVideoGeneric, RespectsMaxPayloadSize) {
  const size_t kPayloadSize = 50;
  const uint8_t kPayload[kPayloadSize] = {};

  RtpPacketizer::PayloadSizeLimits limits;
  limits.max_payload_len = 6;
  RtpPacketizerGeneric packetizer(kPayload, limits, RTPVideoHeader(),
                                  VideoFrameType::kVideoFrameKey);

  std::vector<int> payload_sizes = NextPacketFillPayloadSizes(&packetizer);

  EXPECT_THAT(payload_sizes, Each(Le(limits.max_payload_len)));
}

TEST(RtpPacketizerVideoGeneric, UsesMaxPayloadSize) {
  const size_t kPayloadSize = 50;
  const uint8_t kPayload[kPayloadSize] = {};

  RtpPacketizer::PayloadSizeLimits limits;
  limits.max_payload_len = 6;
  RtpPacketizerGeneric packetizer(kPayload, limits, RTPVideoHeader(),
                                  VideoFrameType::kVideoFrameKey);

  std::vector<int> payload_sizes = NextPacketFillPayloadSizes(&packetizer);

  // With kPayloadSize > max_payload_len^2, there should be packets that use
  // all the payload, otherwise it is possible to use less packets.
  EXPECT_THAT(payload_sizes, Contains(limits.max_payload_len));
}

TEST(RtpPacketizerVideoGeneric, WritesExtendedHeaderWhenPictureIdIsSet) {
  const size_t kPayloadSize = 13;
  const uint8_t kPayload[kPayloadSize] = {};

  RTPVideoHeader rtp_video_header;
  rtp_video_header.generic.emplace().frame_id = 37;
  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, rtp_video_header,
                                  VideoFrameType::kVideoFrameKey);

  RtpPacketToSend packet(nullptr);
  ASSERT_TRUE(packetizer.NextPacket(&packet));

  rtc::ArrayView<const uint8_t> payload = packet.payload();
  EXPECT_EQ(payload.size(), 3 + kPayloadSize);
  EXPECT_TRUE(payload[0] & 0x04);  // Extended header bit is set.
  // Frame id is 37.
  EXPECT_EQ(0u, payload[1]);
  EXPECT_EQ(37u, payload[2]);
}

TEST(RtpPacketizerVideoGeneric, RespectsMaxPayloadSizeWithExtendedHeader) {
  const int kPayloadSize = 50;
  const uint8_t kPayload[kPayloadSize] = {};

  RtpPacketizer::PayloadSizeLimits limits;
  limits.max_payload_len = 6;
  RTPVideoHeader rtp_video_header;
  rtp_video_header.generic.emplace().frame_id = 37;
  RtpPacketizerGeneric packetizer(kPayload, limits, rtp_video_header,
                                  VideoFrameType::kVideoFrameKey);

  std::vector<int> payload_sizes = NextPacketFillPayloadSizes(&packetizer);

  EXPECT_THAT(payload_sizes, Each(Le(limits.max_payload_len)));
}

TEST(RtpPacketizerVideoGeneric, UsesMaxPayloadSizeWithExtendedHeader) {
  const int kPayloadSize = 50;
  const uint8_t kPayload[kPayloadSize] = {};

  RtpPacketizer::PayloadSizeLimits limits;
  limits.max_payload_len = 6;
  RTPVideoHeader rtp_video_header;
  rtp_video_header.generic.emplace().frame_id = 37;
  RtpPacketizerGeneric packetizer(kPayload, limits, rtp_video_header,
                                  VideoFrameType::kVideoFrameKey);
  std::vector<int> payload_sizes = NextPacketFillPayloadSizes(&packetizer);

  // With kPayloadSize > max_payload_len^2, there should be packets that use
  // all the payload, otherwise it is possible to use less packets.
  EXPECT_THAT(payload_sizes, Contains(limits.max_payload_len));
}

TEST(RtpPacketizerVideoGeneric, FrameIdOver15bitsWrapsAround) {
  const int kPayloadSize = 13;
  const uint8_t kPayload[kPayloadSize] = {};

  RTPVideoHeader rtp_video_header;
  rtp_video_header.generic.emplace().frame_id = 0x8137;
  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, rtp_video_header,
                                  VideoFrameType::kVideoFrameKey);

  RtpPacketToSend packet(nullptr);
  ASSERT_TRUE(packetizer.NextPacket(&packet));

  rtc::ArrayView<const uint8_t> payload = packet.payload();
  EXPECT_TRUE(payload[0] & 0x04);  // Extended header bit is set.
  // Frame id is 0x137.
  EXPECT_EQ(0x01u, payload[1]);
  EXPECT_EQ(0x37u, payload[2]);
}

TEST(RtpPacketizerVideoGeneric, NoFrameIdDoesNotWriteExtendedHeader) {
  const int kPayloadSize = 13;
  const uint8_t kPayload[kPayloadSize] = {};

  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, RTPVideoHeader(),
                                  VideoFrameType::kVideoFrameKey);

  RtpPacketToSend packet(nullptr);
  ASSERT_TRUE(packetizer.NextPacket(&packet));

  rtc::ArrayView<const uint8_t> payload = packet.payload();
  EXPECT_FALSE(payload[0] & 0x04);
}

TEST(RtpPacketizerVideoGeneric, DoesNotWriteHeaderForRawPayload) {
  const uint8_t kPayload[] = {0x05, 0x25, 0x52};

  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits);

  RtpPacketToSend packet(nullptr);
  ASSERT_TRUE(packetizer.NextPacket(&packet));

  rtc::ArrayView<const uint8_t> payload = packet.payload();
  EXPECT_THAT(payload, ElementsAreArray(kPayload));
}

TEST(RtpDepacketizerVideoGeneric, NonExtendedHeaderNoFrameId) {
  const size_t kPayloadLen = 1;
  uint8_t payload[kPayloadLen] = {0x01};

  RtpDepacketizerGeneric depacketizer(/*generic_header_enabled=*/true);
  RtpDepacketizer::ParsedPayload parsed_payload;
  depacketizer.Parse(&parsed_payload, payload, kPayloadLen);

  EXPECT_FALSE(parsed_payload.video_header().generic);
}

TEST(RtpDepacketizerVideoGeneric, ExtendedHeaderParsesFrameId) {
  const size_t kPayloadLen = 3;
  uint8_t payload[kPayloadLen] = {0x05, 0x13, 0x37};

  RtpDepacketizerGeneric depacketizer(/*generic_header_enabled=*/true);
  RtpDepacketizer::ParsedPayload parsed_payload;
  depacketizer.Parse(&parsed_payload, payload, kPayloadLen);

  ASSERT_TRUE(parsed_payload.video_header().generic);
  EXPECT_EQ(0x1337, parsed_payload.video_header().generic->frame_id);
}

TEST(RtpDepacketizerVideoGeneric, DoesNotParseHeaderForRawPayload) {
  const uint8_t kPayload[] = {0x05, 0x25, 0x52};
  const size_t kPayloadLen = sizeof(kPayload);

  RtpDepacketizerGeneric depacketizer(/*generic_header_enabled=*/false);
  RtpDepacketizer::ParsedPayload parsed_payload;
  depacketizer.Parse(&parsed_payload, kPayload, kPayloadLen);

  EXPECT_FALSE(parsed_payload.video_header().generic);
  EXPECT_THAT(rtc::MakeArrayView<const uint8_t>(parsed_payload.payload,
                                                parsed_payload.payload_length),
              ElementsAreArray(kPayload));
}

}  // namespace
}  // namespace webrtc
