/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * aomedia.org/license/patent-license/.
 */

#include "aom/aom_codec.h"
#include "aom_dsp/aom_dsp_common.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/y4m_video_source.h"
#include "test/i420_video_source.h"
#include "test/util.h"

namespace {
typedef struct {
  // Superblock size
  const unsigned int sb_size;
  // log2(number of tile rows)
  const unsigned int tile_rows;
  // log2(number of tile columns)
  const unsigned int tile_cols;
} uniformTileConfigParam;

static const uniformTileConfigParam uniformTileConfigParams[] = {
  { 128, 0, 0 }, { 128, 0, 2 }, { 128, 2, 0 }, { 128, 1, 2 }, { 128, 2, 2 },
  { 128, 3, 2 }, { 64, 0, 0 },  { 64, 0, 2 },  { 64, 2, 0 },  { 64, 1, 2 },
  { 64, 2, 2 },  { 64, 3, 3 },  { 64, 4, 4 }
};

typedef struct {
  // Superblock size
  const unsigned int sb_size;
  // number of tile widths
  const unsigned int tile_width_count;
  // list of tile widths
  int tile_widths[AOM_MAX_TILE_COLS];
  // number of tile heights
  const unsigned int tile_height_count;
  // list of tile heights
  int tile_heights[AOM_MAX_TILE_ROWS];
} nonUniformTileConfigParam;

const nonUniformTileConfigParam nonUniformTileConfigParams[] = {
  { 64, 1, { 3 }, 1, { 3 } },          { 64, 2, { 1, 2 }, 2, { 1, 2 } },
  { 64, 3, { 2, 3, 4 }, 2, { 2, 3 } }, { 128, 1, { 3 }, 1, { 3 } },
  { 128, 2, { 1, 2 }, 2, { 1, 2 } },   { 128, 3, { 2, 3, 4 }, 2, { 2, 3 } },
};

// Find smallest k>=0 such that (blk_size << k) >= target
static INLINE int tile_log2(int blk_size, int target) {
  int k;
  for (k = 0; (blk_size << k) < target; k++) {
  }
  return k;
}

// This class is used to validate tile configuration for uniform spacing.
class UniformTileConfigTestLarge
    : public ::libaom_test::CodecTestWith3Params<
          libaom_test::TestMode, uniformTileConfigParam, aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  UniformTileConfigTestLarge()
      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
        tile_config_param_(GET_PARAM(2)), end_usage_check_(GET_PARAM(3)) {
    tile_config_violated_ = false;
    max_tile_cols_log2_ = tile_log2(1, AOM_MAX_TILE_COLS);
    max_tile_rows_log2_ = tile_log2(1, AOM_MAX_TILE_ROWS);
  }
  virtual ~UniformTileConfigTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.rc_end_usage = end_usage_check_;
    cfg_.g_threads = 1;
    cfg_.g_lag_in_frames = 19;
  }

  virtual bool DoDecode() const { return 1; }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AV1E_SET_TILE_COLUMNS, tile_config_param_.tile_cols);
      encoder->Control(AV1E_SET_TILE_ROWS, tile_config_param_.tile_rows);
      encoder->Control(AOME_SET_CPUUSED, 5);
      if (end_usage_check_ == AOM_Q) {
        encoder->Control(AOME_SET_QP, 210);
      }
      encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(AV1E_SET_SUPERBLOCK_SIZE,
                       tile_config_param_.sb_size == 64
                           ? AOM_SUPERBLOCK_SIZE_64X64
                           : AOM_SUPERBLOCK_SIZE_128X128);
    }
  }

  virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
                                  libaom_test::Decoder *decoder) {
    EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
    if (AOM_CODEC_OK == res_dec) {
      aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
      aom_tile_info tile_info;
      int config_tile_columns = AOMMIN(1 << (int)tile_config_param_.tile_cols,
                                       1 << max_tile_cols_log2_);
      int config_tile_rows = AOMMIN(1 << (int)tile_config_param_.tile_rows,
                                    1 << max_tile_rows_log2_);

      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_TILE_INFO, &tile_info);
      if (tile_info.tile_columns != config_tile_columns ||
          tile_info.tile_rows != config_tile_rows) {
        tile_config_violated_ = true;
      }
    }
    return AOM_CODEC_OK == res_dec;
  }

  ::libaom_test::TestMode encoding_mode_;
  const uniformTileConfigParam tile_config_param_;
  int max_tile_cols_log2_;
  int max_tile_rows_log2_;
  bool tile_config_violated_;
  aom_rc_mode end_usage_check_;
};

// This class is used to validate tile configuration for non uniform spacing.
class NonUniformTileConfigTestLarge
    : public ::libaom_test::CodecTestWith3Params<
          libaom_test::TestMode, nonUniformTileConfigParam, aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  NonUniformTileConfigTestLarge()
      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
        tile_config_param_(GET_PARAM(2)), rc_end_usage_(GET_PARAM(3)) {
    tile_config_violated_ = false;
  }
  virtual ~NonUniformTileConfigTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.rc_end_usage = rc_end_usage_;
    cfg_.g_threads = 1;
    cfg_.g_lag_in_frames = 35;
    cfg_.rc_target_bitrate = 1000;
    cfg_.tile_width_count = tile_config_param_.tile_width_count;
    memcpy(cfg_.tile_widths, tile_config_param_.tile_widths,
           sizeof(tile_config_param_.tile_widths[0]) *
               tile_config_param_.tile_width_count);
    cfg_.tile_height_count = tile_config_param_.tile_height_count;
    memcpy(cfg_.tile_heights, tile_config_param_.tile_heights,
           sizeof(tile_config_param_.tile_heights[0]) *
               tile_config_param_.tile_height_count);
  }

  virtual bool DoDecode() const { return 1; }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, 5);
      if (rc_end_usage_ == AOM_Q) {
        encoder->Control(AOME_SET_QP, 210);
      }
      encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(AV1E_SET_SUPERBLOCK_SIZE,
                       tile_config_param_.sb_size == 64
                           ? AOM_SUPERBLOCK_SIZE_64X64
                           : AOM_SUPERBLOCK_SIZE_128X128);
    }
  }

  virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
                                  libaom_test::Decoder *decoder) {
    EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
    if (AOM_CODEC_OK == res_dec) {
      aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
      aom_tile_info tile_info;
      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_TILE_INFO, &tile_info);

      // check validity of tile cols
      int tile_col_idx, tile_col = 0;
      for (tile_col_idx = 0; tile_col_idx < tile_info.tile_columns - 1;
           tile_col_idx++) {
        if (tile_config_param_.tile_widths[tile_col] !=
            tile_info.tile_widths[tile_col_idx])
          tile_config_violated_ = true;
        tile_col = (tile_col + 1) % (int)tile_config_param_.tile_width_count;
      }
      // last column may not be able to accommodate config, but if it is
      // greater than what is configured, there is a violation.
      if (tile_config_param_.tile_widths[tile_col] <
          tile_info.tile_widths[tile_col_idx])
        tile_config_violated_ = true;

      // check validity of tile rows
      int tile_row_idx, tile_row = 0;
      for (tile_row_idx = 0; tile_row_idx < tile_info.tile_rows - 1;
           tile_row_idx++) {
        if (tile_config_param_.tile_heights[tile_row] !=
            tile_info.tile_heights[tile_row_idx])
          tile_config_violated_ = true;
        tile_row = (tile_row + 1) % (int)tile_config_param_.tile_height_count;
      }
      // last row may not be able to accommodate config, but if it is
      // greater than what is configured, there is a violation.
      if (tile_config_param_.tile_heights[tile_row] <
          tile_info.tile_heights[tile_row_idx])
        tile_config_violated_ = true;
    }
    return AOM_CODEC_OK == res_dec;
  }

  ::libaom_test::TestMode encoding_mode_;
  const nonUniformTileConfigParam tile_config_param_;
  bool tile_config_violated_;
  aom_rc_mode rc_end_usage_;
};

TEST_P(UniformTileConfigTestLarge, UniformTileConfigTest) {
  ::libaom_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 1);
  ASSERT_NO_FATAL_FAILURE(video.Begin());

  int max_tiles_cols = video.img()->w / (int)tile_config_param_.sb_size;
  int max_tiles_rows = video.img()->h / (int)tile_config_param_.sb_size;
  max_tile_cols_log2_ = tile_log2(1, AOMMIN(max_tiles_cols, AOM_MAX_TILE_COLS));
  max_tile_rows_log2_ = tile_log2(1, AOMMIN(max_tiles_rows, AOM_MAX_TILE_ROWS));

  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  ASSERT_EQ(tile_config_violated_, false);
}

TEST_P(UniformTileConfigTestLarge, UniformTileConfigTestLowRes) {
  ::libaom_test::Y4mVideoSource video("screendata.y4m", 0, 1);
  ASSERT_NO_FATAL_FAILURE(video.Begin());

  int max_tiles_cols = video.img()->w / (int)tile_config_param_.sb_size;
  int max_tiles_rows = video.img()->h / (int)tile_config_param_.sb_size;
  max_tile_cols_log2_ = tile_log2(1, AOMMIN(max_tiles_cols, AOM_MAX_TILE_COLS));
  max_tile_rows_log2_ = tile_log2(1, AOMMIN(max_tiles_rows, AOM_MAX_TILE_ROWS));

  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  ASSERT_EQ(tile_config_violated_, false);
}

TEST_P(NonUniformTileConfigTestLarge, NonUniformTileConfigTest) {
  ::libaom_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 1);
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  ASSERT_EQ(tile_config_violated_, false);
}

AV1_INSTANTIATE_TEST_SUITE(UniformTileConfigTestLarge, GOODQUALITY_TEST_MODES,
                           ::testing::ValuesIn(uniformTileConfigParams),
                           ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ));

AV1_INSTANTIATE_TEST_SUITE(NonUniformTileConfigTestLarge,
                           GOODQUALITY_TEST_MODES,
                           ::testing::ValuesIn(nonUniformTileConfigParams),
                           ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ));

typedef struct {
  // Number of tile groups to set.
  const int num_tg;
  // Number of tile rows to set
  const int num_tile_rows;
  // Number of tile columns to set
  const int num_tile_cols;
} TileGroupConfigParams;

static const TileGroupConfigParams tileGroupTestParams[] = {
  { 5, 4, 4 }, { 3, 3, 3 }, { 5, 3, 3 }, { 7, 5, 5 }, { 7, 3, 3 }, { 7, 4, 4 }
};

std::ostream &operator<<(std::ostream &os,
                         const TileGroupConfigParams &test_arg) {
  return os << "TileGroupConfigParams { num_tg:" << test_arg.num_tg
            << " num_tile_rows:" << test_arg.num_tile_rows
            << " num_tile_cols:" << test_arg.num_tile_cols << " }";
}

// This class is used to test number of tile groups present in header.
class TileGroupTestLarge
    : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode,
                                                 TileGroupConfigParams>,
      public ::libaom_test::EncoderTest {
 protected:
  TileGroupTestLarge()
      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
        tile_group_config_params_(GET_PARAM(2)) {
    tile_group_config_violated_ = false;
  }
  virtual ~TileGroupTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.rc_end_usage = AOM_Q;
    cfg_.g_threads = 1;
  }

  virtual bool DoDecode() const { return 1; }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, 5);
      encoder->Control(AV1E_SET_NUM_TG, tile_group_config_params_.num_tg);
      encoder->Control(AV1E_SET_TILE_COLUMNS,
                       tile_group_config_params_.num_tile_cols);
      encoder->Control(AV1E_SET_TILE_ROWS,
                       tile_group_config_params_.num_tile_rows);
    }
  }

  virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
                                  libaom_test::Decoder *decoder) {
    EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
    if (AOM_CODEC_OK == res_dec) {
      aom_tile_info tile_info;
      aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_TILE_INFO, &tile_info);
      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_SHOW_EXISTING_FRAME_FLAG,
                                    &show_existing_frame_);
      if (tile_info.num_tile_groups != tile_group_config_params_.num_tg &&
          !show_existing_frame_)
        tile_group_config_violated_ = true;
      EXPECT_EQ(tile_group_config_violated_, false);
    }
    return AOM_CODEC_OK == res_dec;
  }

  int show_existing_frame_;
  bool tile_group_config_violated_;
  aom_rc_mode end_usage_check_;
  ::libaom_test::TestMode encoding_mode_;
  const TileGroupConfigParams tile_group_config_params_;
};

TEST_P(TileGroupTestLarge, TileGroupCountTest) {
  libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480,
                                     cfg_.g_timebase.den, cfg_.g_timebase.num,
                                     0, 5);
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}

AV1_INSTANTIATE_TEST_SUITE(TileGroupTestLarge, GOODQUALITY_TEST_MODES,
                           ::testing::ValuesIn(tileGroupTestParams));
}  // namespace
