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

#include "api/array_view.h"
#include "api/transport/rtp/dependency_descriptor.h"
#include "common_video/generic_frame_descriptor/generic_frame_info.h"
#include "test/gmock.h"

namespace webrtc {
namespace {

using ::testing::Each;

TEST(RtpDependencyDescriptorExtensionTest, Writer3BytesForPerfectTemplate) {
  uint8_t buffer[3];
  FrameDependencyStructure structure;
  structure.num_decode_targets = 2;
  structure.num_chains = 2;
  structure.templates = {
      FrameDependencyTemplate().Dtis("SR").FrameDiffs({1}).ChainDiffs({2, 2})};
  DependencyDescriptor descriptor;
  descriptor.frame_dependencies = structure.templates[0];

  EXPECT_EQ(RtpDependencyDescriptorExtension::ValueSize(structure, descriptor),
            3u);
  EXPECT_TRUE(
      RtpDependencyDescriptorExtension::Write(buffer, structure, descriptor));
}

TEST(RtpDependencyDescriptorExtensionTest, WriteZeroInUnusedBits) {
  uint8_t buffer[32];
  std::memset(buffer, 0xff, sizeof(buffer));
  FrameDependencyStructure structure;
  structure.num_decode_targets = 2;
  structure.num_chains = 2;
  structure.templates = {
      FrameDependencyTemplate().Dtis("SR").FrameDiffs({1}).ChainDiffs({1, 1})};
  DependencyDescriptor descriptor;
  descriptor.frame_dependencies = structure.templates[0];
  descriptor.frame_dependencies.frame_diffs = {2};

  // To test unused bytes are zeroed, need a buffer large enough.
  size_t value_size =
      RtpDependencyDescriptorExtension::ValueSize(structure, descriptor);
  ASSERT_LT(value_size, sizeof(buffer));

  ASSERT_TRUE(
      RtpDependencyDescriptorExtension::Write(buffer, structure, descriptor));

  const uint8_t* unused_bytes = buffer + value_size;
  size_t num_unused_bytes = buffer + sizeof(buffer) - unused_bytes;
  // Check remaining bytes are zeroed.
  EXPECT_THAT(rtc::MakeArrayView(unused_bytes, num_unused_bytes), Each(0));
}

// In practice chain diff for inactive chain will grow uboundly because no
// frames are produced for it, that shouldn't block writing the extension.
TEST(RtpDependencyDescriptorExtensionTest,
     TemplateMatchingSkipsInactiveChains) {
  uint8_t buffer[3];
  FrameDependencyStructure structure;
  structure.num_decode_targets = 2;
  structure.num_chains = 2;
  structure.templates = {
      FrameDependencyTemplate().Dtis("SR").ChainDiffs({2, 2})};
  DependencyDescriptor descriptor;
  descriptor.frame_dependencies = structure.templates[0];

  // Set only 1st chain as active.
  std::bitset<32> active_chains = 0b01;
  descriptor.frame_dependencies.chain_diffs[1] = 1000;

  // Expect perfect template match since the only difference is for an inactive
  // chain. Pefect template match consumes 3 bytes.
  EXPECT_EQ(RtpDependencyDescriptorExtension::ValueSize(
                structure, active_chains, descriptor),
            3u);
  EXPECT_TRUE(RtpDependencyDescriptorExtension::Write(
      buffer, structure, active_chains, descriptor));
}

TEST(RtpDependencyDescriptorExtensionTest,
     AcceptsInvalidChainDiffForInactiveChainWhenChainsAreCustom) {
  uint8_t buffer[256];
  FrameDependencyStructure structure;
  structure.num_decode_targets = 2;
  structure.num_chains = 2;
  structure.templates = {
      FrameDependencyTemplate().Dtis("SR").ChainDiffs({2, 2})};
  DependencyDescriptor descriptor;
  descriptor.frame_dependencies = structure.templates[0];

  // Set only 1st chain as active.
  std::bitset<32> active_chains = 0b01;
  // Set chain_diff different to the template to make it custom.
  descriptor.frame_dependencies.chain_diffs[0] = 1;
  // Set chain diff for inactive chain beyound limit of 255 max chain diff.
  descriptor.frame_dependencies.chain_diffs[1] = 1000;

  // Because chains are custom, should use more than base 3 bytes.
  EXPECT_GT(RtpDependencyDescriptorExtension::ValueSize(
                structure, active_chains, descriptor),
            3u);
  EXPECT_TRUE(RtpDependencyDescriptorExtension::Write(
      buffer, structure, active_chains, descriptor));
}

TEST(RtpDependencyDescriptorExtensionTest, FailsToWriteInvalidDescriptor) {
  uint8_t buffer[256];
  FrameDependencyStructure structure;
  structure.num_decode_targets = 2;
  structure.num_chains = 2;
  structure.templates = {
      FrameDependencyTemplate().T(0).Dtis("SR").ChainDiffs({2, 2})};
  DependencyDescriptor descriptor;
  descriptor.frame_dependencies = structure.templates[0];
  descriptor.frame_dependencies.temporal_id = 1;

  EXPECT_EQ(
      RtpDependencyDescriptorExtension::ValueSize(structure, 0b11, descriptor),
      0u);
  EXPECT_FALSE(RtpDependencyDescriptorExtension::Write(buffer, structure, 0b11,
                                                       descriptor));
}

}  // namespace
}  // namespace webrtc
