/*
 *  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/video_coding/frame_dependencies_calculator.h"

#include "api/video/video_frame_type.h"
#include "common_video/generic_frame_descriptor/generic_frame_info.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::UnorderedElementsAre;

constexpr VideoFrameType kVideoFrameKey = VideoFrameType::kVideoFrameKey;
constexpr VideoFrameType kVideoFrameDelta = VideoFrameType::kVideoFrameDelta;

constexpr CodecBufferUsage ReferenceAndUpdate(int id) {
  return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/true);
}
constexpr CodecBufferUsage Reference(int id) {
  return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/false);
}
constexpr CodecBufferUsage Update(int id) {
  return CodecBufferUsage(id, /*referenced=*/false, /*updated=*/true);
}

TEST(FrameDependenciesCalculatorTest, SingleLayer) {
  CodecBufferUsage pattern[] = {ReferenceAndUpdate(0)};
  FrameDependenciesCalculator calculator;

  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern),
      IsEmpty());
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern),
      ElementsAre(1));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern),
      ElementsAre(3));
}

TEST(FrameDependenciesCalculatorTest, TwoTemporalLayers) {
  // Shortened 4-frame pattern:
  // T1:  2---4   6---8 ...
  //      /   /   /   /
  // T0: 1---3---5---7 ...
  CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
  CodecBufferUsage pattern1[] = {Reference(0), Update(1)};
  CodecBufferUsage pattern2[] = {ReferenceAndUpdate(0)};
  CodecBufferUsage pattern3[] = {Reference(0), Reference(1)};
  FrameDependenciesCalculator calculator;

  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern0),
      IsEmpty());
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/2, pattern1),
      ElementsAre(1));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern2),
      ElementsAre(1));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/4, pattern3),
      UnorderedElementsAre(2, 3));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/5, pattern0),
      ElementsAre(3));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern1),
      ElementsAre(5));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/7, pattern2),
      ElementsAre(5));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/8, pattern3),
      UnorderedElementsAre(6, 7));
}

TEST(FrameDependenciesCalculatorTest, ThreeTemporalLayers4FramePattern) {
  // T2:   2---4   6---8 ...
  //      /   /   /   /
  // T1:  |  3    |  7   ...
  //      /_/     /_/
  // T0: 1-------5-----  ...
  CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
  CodecBufferUsage pattern1[] = {Reference(0), Update(2)};
  CodecBufferUsage pattern2[] = {Reference(0), Update(1)};
  CodecBufferUsage pattern3[] = {Reference(0), Reference(1), Reference(2)};
  FrameDependenciesCalculator calculator;

  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern0),
      IsEmpty());
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/2, pattern1),
      ElementsAre(1));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern2),
      ElementsAre(1));
  // Note that frame#4 references buffer#0 that is updated by frame#1,
  // yet there is no direct dependency from frame#4 to frame#1.
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/4, pattern3),
      UnorderedElementsAre(2, 3));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/5, pattern0),
      ElementsAre(1));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern1),
      ElementsAre(5));
}

TEST(FrameDependenciesCalculatorTest, SimulcastWith2Layers) {
  // S1: 2---4---6-  ...
  //
  // S0: 1---3---5-  ...
  CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
  CodecBufferUsage pattern1[] = {ReferenceAndUpdate(1)};
  FrameDependenciesCalculator calculator;

  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern0),
      IsEmpty());
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/2, pattern1),
      IsEmpty());
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern0),
      ElementsAre(1));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/4, pattern1),
      ElementsAre(2));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/5, pattern0),
      ElementsAre(3));
  EXPECT_THAT(
      calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern1),
      ElementsAre(4));
}

}  // namespace
}  // namespace webrtc
