/*
 *  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 "webrtc/api/array_view.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"

namespace webrtc {
namespace {

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

const size_t kMaxPayloadSize = 1200;

uint8_t kTestPayload[kMaxPayloadSize];

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

size_t GetEffectivePacketsSizeDifference(std::vector<size_t>* payload_sizes,
                                         size_t last_packet_reduction_len) {
  // Account for larger last packet header.
  payload_sizes->back() += last_packet_reduction_len;
  auto minmax =
      std::minmax_element(payload_sizes->begin(), payload_sizes->end());
  // MAX-MIN
  size_t difference = *minmax.second - *minmax.first;
  // Revert temporary changes.
  payload_sizes->back() -= last_packet_reduction_len;
  return difference;
}

}  // namespace

TEST(RtpPacketizerVideoGeneric, AllPacketsMayBeEqual_RespectsMaxPayloadSize) {
  const size_t kMaxPayloadLen = 6;
  const size_t kLastPacketReductionLen = 2;
  const size_t kPayloadSize = 13;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  EXPECT_THAT(payload_sizes, Each(Le(kMaxPayloadLen)));
}

TEST(RtpPacketizerVideoGeneric,
     AllPacketsMayBeEqual_RespectsLastPacketReductionLength) {
  const size_t kMaxPayloadLen = 6;
  const size_t kLastPacketReductionLen = 2;
  const size_t kPayloadSize = 13;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  EXPECT_LE(payload_sizes.back(), kMaxPayloadLen - kLastPacketReductionLen);
}

TEST(RtpPacketizerVideoGeneric,
     AllPacketsMayBeEqual_MakesPacketsAlmostEqualInSize) {
  const size_t kMaxPayloadLen = 6;
  const size_t kLastPacketReductionLen = 2;
  const size_t kPayloadSize = 13;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  size_t sizes_difference = GetEffectivePacketsSizeDifference(
      &payload_sizes, kLastPacketReductionLen);
  EXPECT_LE(sizes_difference, 1u);
}

TEST(RtpPacketizerVideoGeneric,
     AllPacketsMayBeEqual_GeneratesMinimumNumberOfPackets) {
  const size_t kMaxPayloadLen = 6;
  const size_t kLastPacketReductionLen = 3;
  const size_t kPayloadSize = 13;
  // Computed by hand. 3 packets would have capacity 3*(6-1)-3=12 (max length -
  // generic header lengh for each packet minus last packet reduction).
  // 4 packets is enough for kPayloadSize.
  const size_t kMinNumPackets = 4;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  EXPECT_EQ(num_packets, kMinNumPackets);
}

TEST(RtpPacketizerVideoGeneric, SomePacketsAreSmaller_RespectsMaxPayloadSize) {
  const size_t kMaxPayloadLen = 8;
  const size_t kLastPacketReductionLen = 5;
  const size_t kPayloadSize = 28;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  EXPECT_THAT(payload_sizes, Each(Le(kMaxPayloadLen)));
}

TEST(RtpPacketizerVideoGeneric,
     SomePacketsAreSmaller_RespectsLastPacketReductionLength) {
  const size_t kMaxPayloadLen = 8;
  const size_t kLastPacketReductionLen = 5;
  const size_t kPayloadSize = 28;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  EXPECT_LE(payload_sizes.back(), kMaxPayloadLen - kLastPacketReductionLen);
}

TEST(RtpPacketizerVideoGeneric,
     SomePacketsAreSmaller_MakesPacketsAlmostEqualInSize) {
  const size_t kMaxPayloadLen = 8;
  const size_t kLastPacketReductionLen = 5;
  const size_t kPayloadSize = 28;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  size_t sizes_difference = GetEffectivePacketsSizeDifference(
      &payload_sizes, kLastPacketReductionLen);
  EXPECT_LE(sizes_difference, 1u);
}

TEST(RtpPacketizerVideoGeneric,
     SomePacketsAreSmaller_GeneratesMinimumNumberOfPackets) {
  const size_t kMaxPayloadLen = 8;
  const size_t kLastPacketReductionLen = 5;
  const size_t kPayloadSize = 28;
  // Computed by hand. 4 packets would have capacity 4*(8-1)-5=23 (max length -
  // generic header lengh for each packet minus last packet reduction).
  // 5 packets is enough for kPayloadSize.
  const size_t kMinNumPackets = 5;
  RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
                                  kLastPacketReductionLen);
  size_t num_packets =
      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
  EXPECT_THAT(payload_sizes, SizeIs(num_packets));

  EXPECT_EQ(num_packets, kMinNumPackets);
}

}  // namespace webrtc
