/*
 *  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 <optional>
#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}),
                         }));

TEST(ParseResolutionFromFileNameTest, ParseResolutionFromFileName) {
  EXPECT_EQ(ParseResolutionFromFileName("vidyo1_1280x720_30.yuv"),
            (Resolution{.width = 1280, .height = 720}));
  EXPECT_EQ(ParseResolutionFromFileName("vidyo4_1280x720_30"),
            (Resolution{.width = 1280, .height = 720}));
  EXPECT_EQ(ParseResolutionFromFileName("vidyo1_320x180_15.yuv"),
            (Resolution{.width = 320, .height = 180}));
  EXPECT_EQ(ParseResolutionFromFileName("vidyo3_720p_60fps.y4m"),
            (Resolution{.width = 1280, .height = 720}));
  EXPECT_EQ(ParseResolutionFromFileName("ConferenceMotion_1280_720_50.yuv"),
            (Resolution{.width = 1280, .height = 720}));
  EXPECT_EQ(ParseResolutionFromFileName("difficult_photo_1850_1110.yuv"),
            (Resolution{.width = 1850, .height = 1110}));
  EXPECT_EQ(ParseResolutionFromFileName("foreman_128x96.yuv"),
            (Resolution{.width = 128, .height = 96}));
  EXPECT_EQ(ParseResolutionFromFileName("foreman_cif_short.yuv"),
            (Resolution{.width = 352, .height = 288}));
  EXPECT_EQ(ParseResolutionFromFileName("paris_qcif.yuv"),
            (Resolution{.width = 176, .height = 144}));
  EXPECT_EQ(ParseResolutionFromFileName("clip1_qvga.yuv"),
            (Resolution{.width = 320, .height = 240}));
  EXPECT_EQ(ParseResolutionFromFileName("clip1_vga.yuv"),
            (Resolution{.width = 640, .height = 480}));
  EXPECT_EQ(ParseResolutionFromFileName("unknown_clip.yuv"), std::nullopt);
}

}  // namespace test
}  // namespace webrtc
