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

#include <vector>

#include "api/video/encoded_frame.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::IsEmpty;
using ::testing::Matches;

MATCHER_P(FrameWithId, id, "") {
  return Matches(Eq(id))(arg->Id());
}

class FakeEncodedFrame : public EncodedFrame {
 public:
  int64_t ReceivedTime() const override { return 0; }
  int64_t RenderTime() const override { return 0; }
};

class Builder {
 public:
  Builder& Time(uint32_t rtp_timestamp) {
    rtp_timestamp_ = rtp_timestamp;
    return *this;
  }
  Builder& Id(int64_t frame_id) {
    frame_id_ = frame_id;
    return *this;
  }
  Builder& AsLast() {
    last_spatial_layer_ = true;
    return *this;
  }
  Builder& Refs(const std::vector<int64_t>& references) {
    references_ = references;
    return *this;
  }

  std::unique_ptr<FakeEncodedFrame> Build() {
    RTC_CHECK_LE(references_.size(), EncodedFrame::kMaxFrameReferences);
    RTC_CHECK(rtp_timestamp_.has_value());
    RTC_CHECK(frame_id_.has_value());

    auto frame = std::make_unique<FakeEncodedFrame>();
    frame->SetTimestamp(*rtp_timestamp_);
    frame->SetId(*frame_id_);
    frame->is_last_spatial_layer = last_spatial_layer_;

    for (int64_t ref : references_) {
      frame->references[frame->num_references] = ref;
      frame->num_references++;
    }

    return frame;
  }

 private:
  absl::optional<uint32_t> rtp_timestamp_;
  absl::optional<int64_t> frame_id_;
  bool last_spatial_layer_ = false;
  std::vector<int64_t> references_;
};

TEST(FrameBuffer3Test, RejectInvalidRefs) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  // Ref must be less than the id of this frame.
  buffer.InsertFrame(Builder().Time(0).Id(0).Refs({0}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));

  // Duplicate ids are also invalid.
  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1, 1}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
}

TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));

  buffer.InsertFrame(Builder().Time(10).Id(1).Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));

  buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(2));
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
}

TEST(FrameBuffer3Test, LastContinuousFrameReordering) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));

  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(3));
}

TEST(FrameBuffer3Test, LastContinuousTemporalUnit) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  buffer.InsertFrame(Builder().Time(10).Id(1).Build());
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
  buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
}

TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  buffer.InsertFrame(Builder().Time(10).Id(1).Build());
  buffer.InsertFrame(Builder().Time(20).Id(3).Refs({1}).Build());
  buffer.InsertFrame(Builder().Time(20).Id(4).Refs({2, 3}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));

  buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(4));
}

TEST(FrameBuffer3Test, NextDecodable) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(),
              Eq(absl::nullopt));
  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U));
}

TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U));

  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(1)));
  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U));
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(2)));
  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(30U));
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(3)));
}

TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());
  EXPECT_THAT(buffer.LastDecodableTemporalUnitRtpTimestamp(), Eq(10U));

  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(1)));
  EXPECT_THAT(buffer.LastDecodableTemporalUnitRtpTimestamp(), Eq(30U));
}

TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

  buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build());
  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U));

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U));
}

TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {
  FrameBuffer buffer(/*max_frame_slots=*/5, /*max_decode_history=*/10);
  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(40).Id(4).Refs({3}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(50).Id(5).Refs({4}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5));

  // Frame buffer is full
  buffer.InsertFrame(Builder().Time(60).Id(6).Refs({5}).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5));

  buffer.InsertFrame(Builder().Time(70).Id(7).AsLast().Build());
  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(7));
}

TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());

  buffer.ExtractNextDecodableTemporalUnit();
  buffer.DropNextDecodableTemporalUnit();
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(3)));
}

TEST(FrameBuffer3Test, OldFramesAreIgnored) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());

  buffer.ExtractNextDecodableTemporalUnit();
  buffer.ExtractNextDecodableTemporalUnit();

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());

  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(3)));
}

TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  buffer.InsertFrame(Builder().Time(10).Id(1).Build());
  buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).Build());
  buffer.InsertFrame(Builder().Time(10).Id(3).Refs({2}).AsLast().Build());
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(1), FrameWithId(2), FrameWithId(3)));

  buffer.InsertFrame(Builder().Time(20).Id(4).Refs({3}).AsLast().Build());
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(4)));
}

TEST(FrameBuffer3Test, InterleavedStream) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(40).Id(4).Refs({2}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(50).Id(5).Refs({3}).AsLast().Build());

  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(1)));
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(2)));
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(3)));
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(4)));
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(5)));

  buffer.InsertFrame(Builder().Time(70).Id(7).Refs({5}).AsLast().Build());
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(7)));
  buffer.InsertFrame(Builder().Time(60).Id(6).Refs({4}).AsLast().Build());
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
  buffer.InsertFrame(Builder().Time(90).Id(9).Refs({7}).AsLast().Build());
  EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
              ElementsAre(FrameWithId(9)));
}

TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
  {
    // WebRTC-LegacyFrameIdJumpBehavior is disabled by default.
    FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

    buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build());
    EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
                ElementsAre(FrameWithId(3)));
    buffer.InsertFrame(Builder().Time(30).Id(2).AsLast().Build());
    EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
  }

  {
    test::ScopedFieldTrials field_trial(
        "WebRTC-LegacyFrameIdJumpBehavior/Enabled/");
    FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);

    buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build());
    EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
                ElementsAre(FrameWithId(3)));
    buffer.InsertFrame(Builder().Time(30).Id(2).Refs({1}).AsLast().Build());
    EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
    buffer.InsertFrame(Builder().Time(40).Id(1).AsLast().Build());
    EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
                ElementsAre(FrameWithId(1)));
  }
}

TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(0));

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));

  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).Build());
  EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));

  buffer.InsertFrame(Builder().Time(40).Id(4).Refs({2}).Build());
  buffer.InsertFrame(Builder().Time(40).Id(5).Refs({3, 4}).AsLast().Build());
  EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));

  // Reordered
  buffer.InsertFrame(Builder().Time(20).Id(3).Refs({2}).AsLast().Build());
  EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(3));
}

TEST(FrameBuffer3Test, TotalNumberOfDroppedFrames) {
  FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
  EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));

  buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
  buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).Build());
  buffer.InsertFrame(Builder().Time(20).Id(3).Refs({2}).AsLast().Build());
  buffer.InsertFrame(Builder().Time(40).Id(4).Refs({1}).Build());
  buffer.InsertFrame(Builder().Time(40).Id(5).Refs({4}).AsLast().Build());

  buffer.ExtractNextDecodableTemporalUnit();
  EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));

  buffer.DropNextDecodableTemporalUnit();
  EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(2));

  buffer.ExtractNextDecodableTemporalUnit();
  EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(2));
}

}  // namespace
}  // namespace webrtc
