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

#include "common/av1_config.h"
#include "test/util.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

#if CONFIG_PC_WIENER
#include "av1/common/restoration.h"
#endif  // CONFIG_PC_WIENER

namespace {

//
// Input buffers containing exactly one Sequence Header OBU.
//
// Each buffer is named according to the OBU storage format (Annex-B vs Low
// Overhead Bitstream Format) and the type of Sequence Header OBU ("Full"
// Sequence Header OBUs vs Sequence Header OBUs with the
// reduced_still_image_flag set).
//
const uint8_t kAnnexBFullSequenceHeaderObu[] = { 0x0c, 0x08, 0x00, 0x00, 0x00,
                                                 0x04, 0x45, 0x7e, 0x3e, 0xff,
                                                 0xfc, 0xc0, 0x20 };
const uint8_t kAnnexBReducedStillImageSequenceHeaderObu[] = {
  0x08, 0x08, 0x18, 0x22, 0x2b, 0xf1, 0xfe, 0xc0, 0x20
};

const uint8_t kLobfFullSequenceHeaderObu[] = { 0x0a, 0x0b, 0x00, 0x00, 0x00,
                                               0x04, 0x45, 0x7e, 0x3e, 0xff,
                                               0xfc, 0xc0, 0x20 };

const uint8_t kLobfReducedStillImageSequenceHeaderObu[] = { 0x0a, 0x07, 0x18,
                                                            0x22, 0x2b, 0xf1,
                                                            0xfe, 0xc0, 0x20 };

const uint8_t kAv1cAllZero[] = { 0, 0, 0, 0 };

// The size of AV1 config when no configOBUs are present at the end of the
// configuration structure.
const size_t kAv1cNoConfigObusSize = 4;

bool VerifyAv1c(const uint8_t *const obu_buffer, size_t obu_buffer_length,
                bool is_annexb) {
  Av1Config av1_config;
  memset(&av1_config, 0, sizeof(av1_config));
  bool parse_ok = get_av1config_from_obu(obu_buffer, obu_buffer_length,
                                         is_annexb, &av1_config) == 0;
  if (parse_ok) {
    EXPECT_EQ(1, av1_config.marker);
    EXPECT_EQ(1, av1_config.version);
    EXPECT_EQ(0, av1_config.seq_profile);
    EXPECT_EQ(0, av1_config.seq_level_idx_0);
    EXPECT_EQ(0, av1_config.seq_tier_0);
    EXPECT_EQ(0, av1_config.high_bitdepth);
    EXPECT_EQ(0, av1_config.twelve_bit);
    EXPECT_EQ(0, av1_config.monochrome);
    EXPECT_EQ(1, av1_config.chroma_subsampling_x);
    EXPECT_EQ(1, av1_config.chroma_subsampling_y);
    EXPECT_EQ(0, av1_config.chroma_sample_position);
    EXPECT_EQ(0, av1_config.initial_presentation_delay_present);
    EXPECT_EQ(0, av1_config.initial_presentation_delay_minus_one);
  }
  return parse_ok && ::testing::Test::HasFailure() == false;
}

TEST(Av1Config, ObuInvalidInputs) {
  Av1Config av1_config;
  memset(&av1_config, 0, sizeof(av1_config));
  ASSERT_EQ(-1, get_av1config_from_obu(NULL, 0, 0, NULL));
  ASSERT_EQ(-1,
            get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0], 0, 0, NULL));
  ASSERT_EQ(
      -1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0],
                                 sizeof(kLobfFullSequenceHeaderObu), 0, NULL));
  ASSERT_EQ(-1, get_av1config_from_obu(NULL, sizeof(kLobfFullSequenceHeaderObu),
                                       0, NULL));
  ASSERT_EQ(-1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0], 0, 0,
                                       &av1_config));
}

TEST(Av1Config, ReadInvalidInputs) {
  Av1Config av1_config;
  memset(&av1_config, 0, sizeof(av1_config));
  size_t bytes_read = 0;
  ASSERT_EQ(-1, read_av1config(NULL, 0, NULL, NULL));
  ASSERT_EQ(-1, read_av1config(NULL, 4, NULL, NULL));
  ASSERT_EQ(-1, read_av1config(&kAv1cAllZero[0], 0, NULL, NULL));
  ASSERT_EQ(-1, read_av1config(&kAv1cAllZero[0], 4, &bytes_read, NULL));
  ASSERT_EQ(-1, read_av1config(NULL, 4, &bytes_read, &av1_config));
}

TEST(Av1Config, WriteInvalidInputs) {
  Av1Config av1_config;
  memset(&av1_config, 0, sizeof(av1_config));
  size_t bytes_written = 0;
  uint8_t av1c_buffer[4] = { 0 };
  ASSERT_EQ(-1, write_av1config(NULL, 0, NULL, NULL));
  ASSERT_EQ(-1, write_av1config(&av1_config, 0, NULL, NULL));
  ASSERT_EQ(-1, write_av1config(&av1_config, 0, &bytes_written, NULL));

  ASSERT_EQ(-1,
            write_av1config(&av1_config, 0, &bytes_written, &av1c_buffer[0]));
  ASSERT_EQ(-1, write_av1config(&av1_config, 4, &bytes_written, NULL));
}

TEST(Av1Config, DISABLED_GetAv1ConfigFromLobfObu) {
  // Test parsing of a Sequence Header OBU with the reduced_still_picture_header
  // unset-- aka a full Sequence Header OBU.
  ASSERT_TRUE(VerifyAv1c(kLobfFullSequenceHeaderObu,
                         sizeof(kLobfFullSequenceHeaderObu), false));

  // Test parsing of a reduced still image Sequence Header OBU.
  ASSERT_TRUE(VerifyAv1c(kLobfReducedStillImageSequenceHeaderObu,
                         sizeof(kLobfReducedStillImageSequenceHeaderObu),
                         false));
}

TEST(Av1Config, DISABLED_GetAv1ConfigFromAnnexBObu) {
  // Test parsing of a Sequence Header OBU with the reduced_still_picture_header
  // unset-- aka a full Sequence Header OBU.
  ASSERT_TRUE(VerifyAv1c(kAnnexBFullSequenceHeaderObu,
                         sizeof(kAnnexBFullSequenceHeaderObu), true));

  // Test parsing of a reduced still image Sequence Header OBU.
  ASSERT_TRUE(VerifyAv1c(kAnnexBReducedStillImageSequenceHeaderObu,
                         sizeof(kAnnexBReducedStillImageSequenceHeaderObu),
                         true));
}

TEST(Av1Config, DISABLED_ReadWriteConfig) {
  Av1Config av1_config;
  memset(&av1_config, 0, sizeof(av1_config));

  // Test writing out the AV1 config.
  size_t bytes_written = 0;
  uint8_t av1c_buffer[4] = { 0 };
  ASSERT_EQ(0, write_av1config(&av1_config, sizeof(av1c_buffer), &bytes_written,
                               &av1c_buffer[0]));
  ASSERT_EQ(kAv1cNoConfigObusSize, bytes_written);
  for (size_t i = 0; i < kAv1cNoConfigObusSize; ++i) {
    ASSERT_EQ(kAv1cAllZero[i], av1c_buffer[i])
        << "Mismatch in output Av1Config at offset=" << i;
  }

  // Test reading the AV1 config.
  size_t bytes_read = 0;
  ASSERT_EQ(0, read_av1config(&kAv1cAllZero[0], sizeof(kAv1cAllZero),
                              &bytes_read, &av1_config));
  ASSERT_EQ(kAv1cNoConfigObusSize, bytes_read);
  ASSERT_EQ(0, write_av1config(&av1_config, sizeof(av1c_buffer), &bytes_written,
                               &av1c_buffer[0]));
  for (size_t i = 0; i < kAv1cNoConfigObusSize; ++i) {
    ASSERT_EQ(kAv1cAllZero[i], av1c_buffer[i])
        << "Mismatch in output Av1Config at offset=" << i;
  }
}

}  // namespace
