/*
 *  Copyright (c) 2018 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 "rtc_tools/frame_analyzer/video_geometry_aligner.h"

#include <cstdint>
#include <vector>

#include "api/scoped_refptr.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_frame_buffer.h"
#include "rtc_tools/frame_analyzer/video_quality_analysis.h"
#include "rtc_tools/video_file_reader.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {
namespace test {

class VideoGeometryAlignerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    reference_video_ =
        OpenYuvFile(ResourcePath("foreman_128x96", "yuv"), 128, 96);
    ASSERT_TRUE(reference_video_);

    // Very simple 4x4 frame used for verying CropAndZoom.
    const uint8_t data_y[] = {0, 1, 2,  3,  4,  5,  6,  7,
                              8, 9, 10, 11, 12, 13, 14, 15};
    const uint8_t data_u[] = {0, 1, 2, 3};
    const uint8_t data_v[] = {0, 1, 2, 3};
    test_frame_ = I420Buffer::Copy(
        /* width= */ 4, /* height= */ 4, data_y, /* stride_y= */ 4, data_u,
        /* stride_u= */ 2, data_v, /* stride_v= */ 2);
  }

  scoped_refptr<Video> reference_video_;
  scoped_refptr<I420BufferInterface> test_frame_;
};

// Teach gtest how to compare CropRegions.
bool operator==(const CropRegion& a, const CropRegion& b) {
  return a.left == b.left && a.top == b.top && a.right == b.right &&
         a.bottom == b.bottom;
}

TEST_F(VideoGeometryAlignerTest, CropAndZoomIdentity) {
  const scoped_refptr<I420BufferInterface> frame =
      reference_video_->GetFrame(0);

  // Assume perfect match, i.e. SSIM == 1.
  CropRegion identity_region;
  EXPECT_EQ(1.0, Ssim(frame, CropAndZoom(identity_region, frame)));
}

TEST_F(VideoGeometryAlignerTest, CropAndZoomLeft) {
  CropRegion region;
  region.left = 2;
  const scoped_refptr<I420BufferInterface> cropped_frame =
      CropAndZoom(region, test_frame_);
  EXPECT_EQ(std::vector<uint8_t>(
                {2, 2, 3, 3, 6, 6, 7, 7, 10, 10, 11, 11, 14, 14, 15, 15}),
            std::vector<uint8_t>(cropped_frame->DataY(),
                                 cropped_frame->DataY() + 16));
  EXPECT_EQ(
      std::vector<uint8_t>({1, 1, 3, 3}),
      std::vector<uint8_t>(cropped_frame->DataU(), cropped_frame->DataU() + 4));
  EXPECT_EQ(
      std::vector<uint8_t>({1, 1, 3, 3}),
      std::vector<uint8_t>(cropped_frame->DataV(), cropped_frame->DataV() + 4));
}

// TODO(magjed): Re-enable when libyuv filtering is updated.
TEST_F(VideoGeometryAlignerTest, DISABLED_CropAndZoomTop) {
  CropRegion region;
  region.top = 2;
  const scoped_refptr<I420BufferInterface> cropped_frame =
      CropAndZoom(region, test_frame_);
  EXPECT_EQ(std::vector<uint8_t>(
                {8, 9, 10, 11, 10, 11, 12, 13, 12, 13, 14, 15, 12, 13, 14, 15}),
            std::vector<uint8_t>(cropped_frame->DataY(),
                                 cropped_frame->DataY() + 16));
  EXPECT_EQ(
      std::vector<uint8_t>({2, 3, 2, 3}),
      std::vector<uint8_t>(cropped_frame->DataU(), cropped_frame->DataU() + 4));
  EXPECT_EQ(
      std::vector<uint8_t>({2, 3, 2, 3}),
      std::vector<uint8_t>(cropped_frame->DataV(), cropped_frame->DataV() + 4));
}

TEST_F(VideoGeometryAlignerTest, CropAndZoomRight) {
  CropRegion region;
  region.right = 2;
  const scoped_refptr<I420BufferInterface> cropped_frame =
      CropAndZoom(region, test_frame_);
  EXPECT_EQ(std::vector<uint8_t>(
                {0, 0, 1, 1, 4, 4, 5, 5, 8, 8, 9, 9, 12, 12, 13, 13}),
            std::vector<uint8_t>(cropped_frame->DataY(),
                                 cropped_frame->DataY() + 16));
  EXPECT_EQ(
      std::vector<uint8_t>({0, 0, 2, 2}),
      std::vector<uint8_t>(cropped_frame->DataU(), cropped_frame->DataU() + 4));
  EXPECT_EQ(
      std::vector<uint8_t>({0, 0, 2, 2}),
      std::vector<uint8_t>(cropped_frame->DataV(), cropped_frame->DataV() + 4));
}

// TODO(magjed): Re-enable when libyuv filtering is updated.
TEST_F(VideoGeometryAlignerTest, DISABLED_CropAndZoomBottom) {
  CropRegion region;
  region.bottom = 2;
  const scoped_refptr<I420BufferInterface> cropped_frame =
      CropAndZoom(region, test_frame_);
  EXPECT_EQ(
      std::vector<uint8_t>({0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 4, 5, 6, 7}),
      std::vector<uint8_t>(cropped_frame->DataY(),
                           cropped_frame->DataY() + 16));
  EXPECT_EQ(
      std::vector<uint8_t>({0, 1, 0, 1}),
      std::vector<uint8_t>(cropped_frame->DataU(), cropped_frame->DataU() + 4));
  EXPECT_EQ(
      std::vector<uint8_t>({0, 1, 0, 1}),
      std::vector<uint8_t>(cropped_frame->DataV(), cropped_frame->DataV() + 4));
}

TEST_F(VideoGeometryAlignerTest, CalculateCropRegionIdentity) {
  const scoped_refptr<I420BufferInterface> frame =
      reference_video_->GetFrame(0);
  CropRegion identity_region;
  EXPECT_EQ(identity_region, CalculateCropRegion(frame, frame));
}

TEST_F(VideoGeometryAlignerTest, CalculateCropRegionArbitrary) {
  // Arbitrary crop region.
  CropRegion crop_region;
  crop_region.left = 2;
  crop_region.top = 4;
  crop_region.right = 5;
  crop_region.bottom = 3;

  const scoped_refptr<I420BufferInterface> frame =
      reference_video_->GetFrame(0);

  EXPECT_EQ(crop_region,
            CalculateCropRegion(frame, CropAndZoom(crop_region, frame)));
}

}  // namespace test
}  // namespace webrtc
