/*
 *  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 <stdio.h>

#include <cstdint>
#include <cstdio>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

#include "api/scoped_refptr.h"
#include "api/video/resolution.h"
#include "api/video/video_frame_buffer.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/frame_reader.h"

namespace webrtc {
namespace test {

namespace {
using Ratio = FrameReader::Ratio;
using RepeatMode = YuvFrameReaderImpl::RepeatMode;

constexpr Resolution kResolution({.width = 1, .height = 1});
constexpr int kDefaultNumFrames = 3;
}  // namespace

class YuvFrameReaderTest : public ::testing::Test {
 protected:
  YuvFrameReaderTest() = default;
  ~YuvFrameReaderTest() override = default;

  void SetUp() override {
    filepath_ =
        test::TempFilename(test::OutputPath(), "yuv_frame_reader_unittest");
    CreateYuvFileAndReader(/*num_frames=*/3, RepeatMode::kSingle);
  }

  void TearDown() override { remove(filepath_.c_str()); }

  void CreateYuvFileAndReader(int num_frames, RepeatMode repeat_mode) {
    FILE* file = fopen(filepath_.c_str(), "wb");
    for (int i = 0; i < num_frames; ++i) {
      uint8_t y = static_cast<uint8_t>(i & 255);
      uint8_t u = static_cast<uint8_t>((i + 1) & 255);
      uint8_t v = static_cast<uint8_t>((i + 2) & 255);
      fwrite(&y, 1, 1, file);
      fwrite(&u, 1, 1, file);
      fwrite(&v, 1, 1, file);
    }
    fclose(file);

    reader_ = CreateYuvFrameReader(filepath_, kResolution, repeat_mode);
  }

  std::string filepath_;
  std::unique_ptr<FrameReader> reader_;
};

TEST_F(YuvFrameReaderTest, num_frames) {
  EXPECT_EQ(kDefaultNumFrames, reader_->num_frames());
}

TEST_F(YuvFrameReaderTest, PullFrame_frameContent) {
  scoped_refptr<I420BufferInterface> buffer = reader_->PullFrame();
  EXPECT_EQ(0u, *buffer->DataY());
  EXPECT_EQ(1u, *buffer->DataU());
  EXPECT_EQ(2u, *buffer->DataV());
}

TEST_F(YuvFrameReaderTest, ReadFrame_randomOrder) {
  scoped_refptr<I420BufferInterface> buffer = reader_->ReadFrame(2);
  EXPECT_EQ(2u, *buffer->DataY());
  buffer = reader_->ReadFrame(0);
  EXPECT_EQ(0u, *buffer->DataY());
  buffer = reader_->ReadFrame(1);
  EXPECT_EQ(1u, *buffer->DataY());
}

TEST_F(YuvFrameReaderTest, PullFrame_scale) {
  scoped_refptr<I420BufferInterface> buffer = reader_->PullFrame(
      /*pulled_frame_num=*/nullptr, Resolution({.width = 2, .height = 2}),
      FrameReader::kNoScale);
  EXPECT_EQ(2, buffer->width());
  EXPECT_EQ(2, buffer->height());
}

class YuvFrameReaderRepeatModeTest
    : public YuvFrameReaderTest,
      public ::testing::WithParamInterface<
          std::tuple<int, RepeatMode, std::vector<uint8_t>>> {};

TEST_P(YuvFrameReaderRepeatModeTest, PullFrame) {
  auto [num_frames, repeat_mode, expected_frames] = GetParam();
  CreateYuvFileAndReader(num_frames, repeat_mode);
  for (auto expected_frame : expected_frames) {
    scoped_refptr<I420BufferInterface> buffer = reader_->PullFrame();
    EXPECT_EQ(expected_frame, *buffer->DataY());
  }
}

INSTANTIATE_TEST_SUITE_P(
    YuvFrameReaderTest,
    YuvFrameReaderRepeatModeTest,
    ::testing::ValuesIn(
        {std::make_tuple(3, RepeatMode::kSingle, std::vector<uint8_t>{0, 1, 2}),
         std::make_tuple(3,
                         RepeatMode::kRepeat,
                         std::vector<uint8_t>{0, 1, 2, 0, 1, 2}),
         std::make_tuple(3,
                         RepeatMode::kPingPong,
                         std::vector<uint8_t>{0, 1, 2, 1, 0, 1, 2}),
         std::make_tuple(1,
                         RepeatMode::kPingPong,
                         std::vector<uint8_t>{0, 0})}));

class YuvFrameReaderFramerateScaleTest
    : public YuvFrameReaderTest,
      public ::testing::WithParamInterface<
          std::tuple<Ratio, std::vector<int>>> {};

TEST_P(YuvFrameReaderFramerateScaleTest, PullFrame) {
  auto [framerate_scale, expected_frames] = GetParam();
  for (auto expected_frame : expected_frames) {
    int pulled_frame;
    scoped_refptr<I420BufferInterface> buffer =
        reader_->PullFrame(&pulled_frame, kResolution, framerate_scale);
    EXPECT_EQ(pulled_frame, expected_frame);
  }
}

INSTANTIATE_TEST_SUITE_P(YuvFrameReaderTest,
                         YuvFrameReaderFramerateScaleTest,
                         ::testing::ValuesIn({
                             std::make_tuple(Ratio({.num = 1, .den = 2}),
                                             std::vector<int>{0, 2, 4}),
                             std::make_tuple(Ratio({.num = 2, .den = 3}),
                                             std::vector<int>{0, 1, 3, 4, 6}),
                             std::make_tuple(Ratio({.num = 2, .den = 1}),
                                             std::vector<int>{0, 0, 1, 1}),
                         }));

}  // namespace test
}  // namespace webrtc
