/*
 *  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 <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_format_video_generic.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

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

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
