// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/avif.h"
#include "aviftest_helpers.h"
#include "gtest/gtest.h"

using testing::Combine;
using testing::Values;

namespace libavif {
namespace {

class AvmTest : public testing::TestWithParam<
                    std::tuple</*width=*/int, /*height=*/int, /*depth=*/int,
                               avifPixelFormat, /*alpha=*/bool>> {};

TEST_P(AvmTest, EncodeDecode) {
  const int width = std::get<0>(GetParam());
  const int height = std::get<1>(GetParam());
  const int depth = std::get<2>(GetParam());
  const avifPixelFormat format = std::get<3>(GetParam());
  const bool alpha = std::get<4>(GetParam());

  testutil::AvifImagePtr image = testutil::CreateImage(
      width, height, depth, format, alpha ? AVIF_PLANES_ALL : AVIF_PLANES_YUV);
  ASSERT_NE(image, nullptr);
  testutil::FillImageGradient(image.get());

  testutil::AvifEncoderPtr encoder(avifEncoderCreate(), avifEncoderDestroy);
  ASSERT_NE(encoder, nullptr);
  encoder->codecChoice = AVIF_CODEC_CHOICE_AVM;
  testutil::AvifRwData encoded;
  ASSERT_EQ(avifEncoderWrite(encoder.get(), image.get(), &encoded),
            AVIF_RESULT_OK);

  testutil::AvifImagePtr decoded(avifImageCreateEmpty(), avifImageDestroy);
  ASSERT_NE(decoded, nullptr);
  testutil::AvifDecoderPtr decoder(avifDecoderCreate(), avifDecoderDestroy);
  ASSERT_NE(decoder, nullptr);
  // No need to set AVIF_CODEC_CHOICE_AVM. The decoder should recognize AV2.
  ASSERT_EQ(avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
                                  encoded.size),
            AVIF_RESULT_OK);

  // Verify that the input and decoded images are close.
  EXPECT_GT(testutil::GetPsnr(*image, *decoded), 40.0);

  // Forcing an AV1 decoding codec should fail.
  for (avifCodecChoice av1_codec :
       {AVIF_CODEC_CHOICE_AOM, AVIF_CODEC_CHOICE_DAV1D,
        AVIF_CODEC_CHOICE_LIBGAV1}) {
    decoder->codecChoice = av1_codec;
    // AVIF_RESULT_NO_CODEC_AVAILABLE is expected because av1_codec is not
    // enabled or because we are trying to decode an AV2 file with an AV1 codec.
    ASSERT_EQ(avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
                                    encoded.size),
              AVIF_RESULT_NO_CODEC_AVAILABLE);
  }
}

INSTANTIATE_TEST_SUITE_P(Basic, AvmTest,
                         Combine(/*width=*/Values(12), /*height=*/Values(34),
                                 /*depth=*/Values(8),
                                 Values(AVIF_PIXEL_FORMAT_YUV420,
                                        AVIF_PIXEL_FORMAT_YUV444),
                                 /*alpha=*/Values(true)));

INSTANTIATE_TEST_SUITE_P(Tiny, AvmTest,
                         Combine(/*width=*/Values(1), /*height=*/Values(1),
                                 /*depth=*/Values(8),
                                 Values(AVIF_PIXEL_FORMAT_YUV444),
                                 /*alpha=*/Values(false)));

// TODO(yguyon): Implement or fix in avm then test the following combinations.
INSTANTIATE_TEST_SUITE_P(DISABLED_Broken, AvmTest,
                         Combine(/*width=*/Values(1), /*height=*/Values(34),
                                 /*depth=*/Values(8, 10, 12),
                                 Values(AVIF_PIXEL_FORMAT_YUV400,
                                        AVIF_PIXEL_FORMAT_YUV420,
                                        AVIF_PIXEL_FORMAT_YUV444),
                                 /*alpha=*/Values(true)));

TEST(AvmTest, Av1StillWorksWhenAvmIsEnabled) {
  if (!testutil::Av1EncoderAvailable() || !testutil::Av1DecoderAvailable()) {
    GTEST_SKIP() << "AV1 codec unavailable, skip test.";
  }
  // avm is the only AV2 codec, so the default codec will be an AV1 one.

  testutil::AvifImagePtr image =
      testutil::CreateImage(/*width=*/64, /*height=*/64, /*depth=*/8,
                            AVIF_PIXEL_FORMAT_YUV420, AVIF_PLANES_ALL);
  ASSERT_NE(image, nullptr);
  testutil::FillImageGradient(image.get());

  testutil::AvifEncoderPtr encoder(avifEncoderCreate(), avifEncoderDestroy);
  ASSERT_NE(encoder, nullptr);
  testutil::AvifRwData encoded;
  ASSERT_EQ(avifEncoderWrite(encoder.get(), image.get(), &encoded),
            AVIF_RESULT_OK);

  testutil::AvifImagePtr decoded(avifImageCreateEmpty(), avifImageDestroy);
  ASSERT_NE(decoded, nullptr);
  testutil::AvifDecoderPtr decoder(avifDecoderCreate(), avifDecoderDestroy);
  ASSERT_NE(decoder, nullptr);
  ASSERT_EQ(avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
                                  encoded.size),
            AVIF_RESULT_OK);

  // Verify that the input and decoded images are close.
  EXPECT_GT(testutil::GetPsnr(*image, *decoded), 40.0);

  // Forcing an AV2 decoding codec should fail.
  decoder->codecChoice = AVIF_CODEC_CHOICE_AVM;
  ASSERT_EQ(avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
                                  encoded.size),
            AVIF_RESULT_NO_CODEC_AVAILABLE);
}

}  // namespace
}  // namespace libavif
