/*
 *  Copyright (c) 2022 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/codecs/test/video_codec_analyzer.h"

#include "absl/types/optional.h"
#include "api/video/i420_buffer.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"

namespace webrtc {
namespace test {

namespace {
using ::testing::Return;
using ::testing::Values;
using Psnr = VideoCodecStats::Frame::Psnr;

const uint32_t kTimestamp = 3000;
const int kSpatialIdx = 2;

class MockReferenceVideoSource
    : public VideoCodecAnalyzer::ReferenceVideoSource {
 public:
  MOCK_METHOD(VideoFrame, GetFrame, (uint32_t, Resolution), (override));
};

VideoFrame CreateVideoFrame(uint32_t timestamp_rtp,
                            uint8_t y = 0,
                            uint8_t u = 0,
                            uint8_t v = 0) {
  rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create(2, 2));

  libyuv::I420Rect(buffer->MutableDataY(), buffer->StrideY(),
                   buffer->MutableDataU(), buffer->StrideU(),
                   buffer->MutableDataV(), buffer->StrideV(), 0, 0,
                   buffer->width(), buffer->height(), y, u, v);

  return VideoFrame::Builder()
      .set_video_frame_buffer(buffer)
      .set_timestamp_rtp(timestamp_rtp)
      .build();
}

EncodedImage CreateEncodedImage(uint32_t timestamp_rtp, int spatial_idx = 0) {
  EncodedImage encoded_image;
  encoded_image.SetTimestamp(timestamp_rtp);
  encoded_image.SetSpatialIndex(spatial_idx);
  return encoded_image;
}
}  // namespace

TEST(VideoCodecAnalyzerTest, StartEncode) {
  VideoCodecAnalyzer analyzer;
  analyzer.StartEncode(CreateVideoFrame(kTimestamp));

  auto fs = analyzer.GetStats()->Slice();
  EXPECT_EQ(1u, fs.size());
  EXPECT_EQ(fs[0].timestamp_rtp, kTimestamp);
}

TEST(VideoCodecAnalyzerTest, FinishEncode) {
  VideoCodecAnalyzer analyzer;
  analyzer.StartEncode(CreateVideoFrame(kTimestamp));

  EncodedImage encoded_frame = CreateEncodedImage(kTimestamp, kSpatialIdx);
  analyzer.FinishEncode(encoded_frame);

  auto fs = analyzer.GetStats()->Slice();
  EXPECT_EQ(2u, fs.size());
  EXPECT_EQ(kSpatialIdx, fs[1].spatial_idx);
}

TEST(VideoCodecAnalyzerTest, StartDecode) {
  VideoCodecAnalyzer analyzer;
  analyzer.StartDecode(CreateEncodedImage(kTimestamp, kSpatialIdx));

  auto fs = analyzer.GetStats()->Slice();
  EXPECT_EQ(1u, fs.size());
  EXPECT_EQ(kTimestamp, fs[0].timestamp_rtp);
}

TEST(VideoCodecAnalyzerTest, FinishDecode) {
  VideoCodecAnalyzer analyzer;
  analyzer.StartDecode(CreateEncodedImage(kTimestamp, kSpatialIdx));
  VideoFrame decoded_frame = CreateVideoFrame(kTimestamp);
  analyzer.FinishDecode(decoded_frame, kSpatialIdx);

  auto fs = analyzer.GetStats()->Slice();
  EXPECT_EQ(1u, fs.size());
  EXPECT_EQ(decoded_frame.width(), fs[0].width);
  EXPECT_EQ(decoded_frame.height(), fs[0].height);
}

TEST(VideoCodecAnalyzerTest, ReferenceVideoSource) {
  MockReferenceVideoSource reference_video_source;
  VideoCodecAnalyzer analyzer(&reference_video_source);
  analyzer.StartDecode(CreateEncodedImage(kTimestamp, kSpatialIdx));

  EXPECT_CALL(reference_video_source, GetFrame)
      .WillOnce(Return(CreateVideoFrame(kTimestamp, /*y=*/0,
                                        /*u=*/0, /*v=*/0)));

  analyzer.FinishDecode(
      CreateVideoFrame(kTimestamp, /*value_y=*/1, /*value_u=*/2, /*value_v=*/3),
      kSpatialIdx);

  auto fs = analyzer.GetStats()->Slice();
  EXPECT_EQ(1u, fs.size());
  EXPECT_TRUE(fs[0].psnr.has_value());

  const Psnr& psnr = *fs[0].psnr;
  EXPECT_NEAR(psnr.y, 48, 1);
  EXPECT_NEAR(psnr.u, 42, 1);
  EXPECT_NEAR(psnr.v, 38, 1);
}

}  // namespace test
}  // namespace webrtc
