/*
 * Copyright (c) 2024, Alliance for Open Media. All rights reserved.
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent.
 */

#include <cmath>

#include "gtest/gtest.h"

#include "examples/multilayer_metadata.h"
#include "test/video_source.h"

namespace libaom_examples {
namespace {

TEST(MultilayerMetadataTest, ParseAlpha) {
  const std::string metadata = R"(

use_case: 1 # global alpha
layers:
  - layer_type: 5 # alpha
    luma_plane_only_flag: 1
    layer_metadata_scope: 2 # global
    alpha:
      alpha_use_idc: 1 # premultiplied
      alpha_bit_depth: 8
      alpha_transparent_value: 0
      alpha_opaque_value: 4

  - layer_type: 1 # texture
    luma_plane_only_flag: 0
    layer_metadata_scope: 2 # global
    layer_color_description:
      color_range: 1
      color_primaries: 1
      transfer_characteristics: 13
      matrix_coefficients: 6

    )";
  libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
  fprintf(tmp_file.file(), "%s", metadata.c_str());
  fflush(tmp_file.file());

  MultilayerMetadata multilayer;
  EXPECT_TRUE(parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));

  EXPECT_EQ(multilayer.use_case, 1);
  ASSERT_EQ(multilayer.layers.size(), 2);
  EXPECT_EQ(multilayer.layers[0].layer_type, 5);
  EXPECT_EQ(multilayer.layers[0].luma_plane_only_flag, 1);
  EXPECT_EQ(multilayer.layers[0].layer_metadata_scope, 2);
  EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_use_idc, 1);
  EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_bit_depth, 8);
  EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_transparent_value, 0);
  EXPECT_EQ(multilayer.layers[0].global_alpha_info.alpha_opaque_value, 4);
  EXPECT_EQ(multilayer.layers[1].layer_type, 1);
  EXPECT_EQ(multilayer.layers[1].luma_plane_only_flag, 0);
  EXPECT_EQ(multilayer.layers[1].layer_metadata_scope, 2);
  EXPECT_TRUE(multilayer.layers[1].layer_color_description.second);
  EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_range, 1);
  EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_primaries,
            1);
  EXPECT_EQ(multilayer.layers[1]
                .layer_color_description.first.transfer_characteristics,
            13);
  EXPECT_EQ(
      multilayer.layers[1].layer_color_description.first.matrix_coefficients,
      6);
}

TEST(MultilayerMetadataTest, ParseDepth) {
  const std::string metadata = R"(
use_case: 2 # global depth
layers:
  - layer_type: 6 # depth
    luma_plane_only_flag: 1
    layer_metadata_scope: 2 # global
    depth:
      z_near: 1.456
      z_far: 9.786
      depth_representation_type: 2

  - layer_type: 1 # texture
    luma_plane_only_flag: 0
    layer_metadata_scope: 2 # global
    layer_color_description:
      color_range: 1
      color_primaries: 1
      transfer_characteristics: 13
      matrix_coefficients: 6

    )";
  libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
  fprintf(tmp_file.file(), "%s", metadata.c_str());
  fflush(tmp_file.file());

  MultilayerMetadata multilayer;
  EXPECT_TRUE(parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
  EXPECT_EQ(multilayer.use_case, 2);
  ASSERT_EQ(multilayer.layers.size(), 2);
  EXPECT_EQ(multilayer.layers[0].layer_type, 6);
  EXPECT_EQ(multilayer.layers[0].luma_plane_only_flag, 1);
  EXPECT_EQ(multilayer.layers[0].layer_metadata_scope, 2);
  EXPECT_TRUE(multilayer.layers[0].global_depth_info.z_near.second);
  EXPECT_NEAR(depth_representation_element_to_double(
                  multilayer.layers[0].global_depth_info.z_near.first),
              1.456, 0.00001);
  EXPECT_TRUE(multilayer.layers[0].global_depth_info.z_far.second);
  EXPECT_NEAR(depth_representation_element_to_double(
                  multilayer.layers[0].global_depth_info.z_far.first),
              9.786, 0.00001);
  EXPECT_EQ(multilayer.layers[0].global_depth_info.depth_representation_type,
            2);
  EXPECT_EQ(multilayer.layers[1].layer_type, 1);
  EXPECT_EQ(multilayer.layers[1].luma_plane_only_flag, 0);
  EXPECT_EQ(multilayer.layers[1].layer_metadata_scope, 2);
  EXPECT_TRUE(multilayer.layers[1].layer_color_description.second);
  EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_range, 1);
  EXPECT_EQ(multilayer.layers[1].layer_color_description.first.color_primaries,
            1);
  EXPECT_EQ(multilayer.layers[1]
                .layer_color_description.first.transfer_characteristics,
            13);
  EXPECT_EQ(
      multilayer.layers[1].layer_color_description.first.matrix_coefficients,
      6);
}

TEST(MultilayerMetadataTest, ParseInvalid) {
  const std::string metadata = R"(

use_case: 1 # global alpha
layers:
  - layer_type: 5 # alpha
    luma_plane_only_flag: 1
    layer_metadata_scope: 2 # global

  - layer_type: 1 # texture
    luma_plane_only_flag: 0
    layer_metadata_scope: 2 # global

  - layer_type: 6 # depth => bad layer type
    luma_plane_only_flag: 1
    layer_metadata_scope: 2 # global
    )";
  libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
  fprintf(tmp_file.file(), "%s", metadata.c_str());
  fflush(tmp_file.file());

  MultilayerMetadata multilayer;
  // Invalid: has a depth layer even though use_case is alpha
  EXPECT_FALSE(
      parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
}

TEST(MultilayerMetadataTest, ParseBadIndent) {
  const std::string metadata = R"(

use_case: 1 # global alpha
layers:
  - layer_type: 5 # alpha
    luma_plane_only_flag: 1
      layer_metadata_scope: 2 # global

  - layer_type: 1 # texture
    luma_plane_only_flag: 0
    layer_metadata_scope: 2 # global
    )";
  libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
  fprintf(tmp_file.file(), "%s", metadata.c_str());
  fflush(tmp_file.file());

  MultilayerMetadata multilayer;
  // Invalid indentation.
  EXPECT_FALSE(
      parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
}

TEST(MultilayerMetadataTest, ParseUnknownField) {
  const std::string metadata = R"(

use_case: 1 # global alpha
layers:
  - layer_type: 5 # alpha
    luma_plane_only_flag: 1
    layer_metadata_scope: 2 # global
    foobar: 42

  - layer_type: 1 # texture
    luma_plane_only_flag: 0
    layer_metadata_scope: 2 # global
    )";
  libaom_test::TempOutFile tmp_file(/*text_mode=*/true);
  fprintf(tmp_file.file(), "%s", metadata.c_str());
  fflush(tmp_file.file());

  MultilayerMetadata multilayer;
  // Unkonwn field 'foobar'.
  EXPECT_FALSE(
      parse_multilayer_file(tmp_file.file_name().c_str(), &multilayer));
}

void TestConversion(double v) {
  DepthRepresentationElement e;
  ASSERT_TRUE(double_to_depth_representation_element(v, &e)) << v;
  EXPECT_NEAR(depth_representation_element_to_double(e), v, 0.000000001);
}

TEST(MultilayerMetadataTest, DoubleConversion) {
  TestConversion(0.0);
  TestConversion(1.789456e-5);
  TestConversion(-1.789456e-5);
  TestConversion(42);
  TestConversion(6.7894564456);
  TestConversion(6.7894564456e10);
  TestConversion(-6.7894564456e10);

  DepthRepresentationElement e;
  // Too small.
  ASSERT_FALSE(double_to_depth_representation_element(1e-10, &e));
  // Too big.
  ASSERT_FALSE(double_to_depth_representation_element(1e+30, &e));
}

}  // namespace
}  // namespace libaom_examples
