/*
 *  Copyright (c) 2019 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 "test/testsupport/video_frame_writer.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <memory>
#include <string>

#include "absl/strings/string_view.h"
#include "api/test/video/video_frame_writer.h"
#include "api/video/i420_buffer.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/frame_reader.h"

namespace webrtc {
namespace test {
namespace {

const size_t kFrameWidth = 50;
const size_t kFrameHeight = 20;
const size_t kFrameLength = 3 * kFrameWidth * kFrameHeight / 2;  // I420.
const size_t kFrameRate = 30;

// Size of header: "YUV4MPEG2 W50 H20 F30:1 C420\n"
const size_t kFileHeaderSize = 29;
// Size of header: "FRAME\n"
const size_t kFrameHeaderSize = 6;

rtc::scoped_refptr<I420Buffer> CreateI420Buffer(int width, int height) {
  rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create(width, height));
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      buffer->MutableDataY()[x + y * width] = 128;
    }
  }
  int chroma_width = buffer->ChromaWidth();
  int chroma_height = buffer->ChromaHeight();
  for (int x = 0; x < chroma_width; x++) {
    for (int y = 0; y < chroma_height; y++) {
      buffer->MutableDataU()[x + y * chroma_width] = 1;
      buffer->MutableDataV()[x + y * chroma_width] = 255;
    }
  }
  return buffer;
}

void AssertI420BuffersEq(
    rtc::scoped_refptr<webrtc::I420BufferInterface> actual,
    rtc::scoped_refptr<webrtc::I420BufferInterface> expected) {
  ASSERT_TRUE(actual);

  ASSERT_EQ(actual->width(), expected->width());
  ASSERT_EQ(actual->height(), expected->height());
  const int width = expected->width();
  const int height = expected->height();
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      ASSERT_EQ(actual->DataY()[x + y * width],
                expected->DataY()[x + y * width]);
    }
  }

  ASSERT_EQ(actual->ChromaWidth(), expected->ChromaWidth());
  ASSERT_EQ(actual->ChromaHeight(), expected->ChromaHeight());
  int chroma_width = expected->ChromaWidth();
  int chroma_height = expected->ChromaHeight();
  for (int x = 0; x < chroma_width; x++) {
    for (int y = 0; y < chroma_height; y++) {
      ASSERT_EQ(actual->DataU()[x + y * chroma_width],
                expected->DataU()[x + y * chroma_width]);
      ASSERT_EQ(actual->DataV()[x + y * chroma_width],
                expected->DataV()[x + y * chroma_width]);
    }
  }
}

}  // namespace

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

  void SetUp() override {
    temp_filename_ = webrtc::test::TempFilename(webrtc::test::OutputPath(),
                                                "video_frame_writer_unittest");
    frame_writer_ = CreateFrameWriter();
  }

  virtual std::unique_ptr<VideoFrameWriter> CreateFrameWriter() = 0;

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

  std::unique_ptr<VideoFrameWriter> frame_writer_;
  std::string temp_filename_;
};

class Y4mVideoFrameWriterTest : public VideoFrameWriterTest {
 protected:
  std::unique_ptr<VideoFrameWriter> CreateFrameWriter() override {
    return std::make_unique<Y4mVideoFrameWriterImpl>(
        temp_filename_, kFrameWidth, kFrameHeight, kFrameRate);
  }
};

class YuvVideoFrameWriterTest : public VideoFrameWriterTest {
 protected:
  std::unique_ptr<VideoFrameWriter> CreateFrameWriter() override {
    return std::make_unique<YuvVideoFrameWriterImpl>(temp_filename_,
                                                     kFrameWidth, kFrameHeight);
  }
};

TEST_F(Y4mVideoFrameWriterTest, InitSuccess) {}

TEST_F(Y4mVideoFrameWriterTest, WriteFrame) {
  rtc::scoped_refptr<I420Buffer> expected_buffer =
      CreateI420Buffer(kFrameWidth, kFrameHeight);

  VideoFrame frame =
      VideoFrame::Builder().set_video_frame_buffer(expected_buffer).build();

  ASSERT_TRUE(frame_writer_->WriteFrame(frame));
  ASSERT_TRUE(frame_writer_->WriteFrame(frame));

  frame_writer_->Close();
  EXPECT_EQ(kFileHeaderSize + 2 * kFrameHeaderSize + 2 * kFrameLength,
            GetFileSize(temp_filename_));

  std::unique_ptr<FrameReader> frame_reader =
      CreateY4mFrameReader(temp_filename_);
  AssertI420BuffersEq(frame_reader->PullFrame(), expected_buffer);
  AssertI420BuffersEq(frame_reader->PullFrame(), expected_buffer);
  EXPECT_FALSE(frame_reader->PullFrame());  // End of file.
}

TEST_F(YuvVideoFrameWriterTest, InitSuccess) {}

TEST_F(YuvVideoFrameWriterTest, WriteFrame) {
  rtc::scoped_refptr<I420Buffer> expected_buffer =
      CreateI420Buffer(kFrameWidth, kFrameHeight);

  VideoFrame frame =
      VideoFrame::Builder().set_video_frame_buffer(expected_buffer).build();

  ASSERT_TRUE(frame_writer_->WriteFrame(frame));
  ASSERT_TRUE(frame_writer_->WriteFrame(frame));

  frame_writer_->Close();
  EXPECT_EQ(2 * kFrameLength, GetFileSize(temp_filename_));

  std::unique_ptr<FrameReader> frame_reader = CreateYuvFrameReader(
      temp_filename_,
      Resolution({.width = kFrameWidth, .height = kFrameHeight}));
  AssertI420BuffersEq(frame_reader->PullFrame(), expected_buffer);
  AssertI420BuffersEq(frame_reader->PullFrame(), expected_buffer);
  EXPECT_FALSE(frame_reader->PullFrame());  // End of file.
}

}  // namespace test
}  // namespace webrtc
