// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "formats/id3/extractor.h"

#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/string_view.h"
#include "formats/byte_range.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

using ::absl_testing::IsOk;
using ::absl_testing::StatusIs;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::Field;
using ::testing::HasSubstr;
using ::testing::Optional;

#ifndef ASSERT_OK_AND_ASSIGN
#define ASSERT_OK_AND_ASSIGN_CONCAT2(x, y) x##y
#define ASSERT_OK_AND_ASSIGN_CONCAT(x, y) ASSERT_OK_AND_ASSIGN_CONCAT2(x, y)

#define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
  ASSERT_OK_AND_ASSIGN_IMPL(lhs, rexpr, __COUNTER__)

#define ASSERT_OK_AND_ASSIGN_IMPL(lhs, rexpr, id)             \
  auto ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id) = (rexpr); \
  ASSERT_THAT(ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id),    \
              ::absl_testing::IsOk());                        \
  lhs = std::move(*ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id))
#endif

constexpr unsigned char kId3TagWithC2paManifestStore[] = {
    'I', 'D', '3',           // ID3 file identifier
    0x03, 0x00,              // Version 2.3
    0x00,                    // Flags
    0x00, 0x00, 0x00, 0x3E,  // Tag size = 62 (52 + 10)
    'G', 'E', 'O', 'B',      // Frame ID
    0x00, 0x00, 0x00, 0x34,  // Frame Size = 52
    0x00, 0x00,              // Frame flags
    0x01,                    // Text encoding [UTF-16]
    // MIME type
    'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'c', '2', 'p',
    'a', 0x00,
    // File name [UTF-16LE]
    0xFF, 0xFE, 'f', 0x00, 'o', 0x00, 'o', 0x00, 0x00, 0x00,
    // Content description [UTF-16LE]
    0xFF, 0xFE, 'b', 0x00, 'a', 0x00, 'r', 0x00, 0x00, 0x00,
    // Encapsulated object
    'm', 'a', 'n', 'i', 'f', 'e', 's', 't', ' ', 's', 't', 'o', 'r', 'e'};

constexpr unsigned char kId3TagWithMultipleC2paManifestStores[] = {
    'I', 'D', '3',           // ID3 file identifier
    0x03, 0x00,              // Version 2.3
    0x00,                    // Flags
    0x00, 0x00, 0x00, 0x7C,  // Tag size = 124 (52 + 10 + 52 + 10)
    // Frame 1
    'G', 'E', 'O', 'B',      // Frame ID
    0x00, 0x00, 0x00, 0x34,  // Frame Size = 52
    0x00, 0x00,              // Frame flags
    0x01,                    // Text encoding [UTF-16]
    // MIME type
    'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'c', '2', 'p',
    'a', 0x00,
    // File name [UTF-16LE]
    0xFF, 0xFE, 'f', 0x00, 'o', 0x00, 'o', 0x00, 0x00, 0x00,
    // Content description [UTF-16LE]
    0xFF, 0xFE, 'b', 0x00, 'a', 0x00, 'r', 0x00, 0x00, 0x00,
    // Encapsulated object
    'm', 'a', 'n', 'i', 'f', 'e', 's', 't', ' ', 's', 't', 'o', 'r', 'e',
    // Frame 2
    'G', 'E', 'O', 'B',      // Frame ID
    0x00, 0x00, 0x00, 0x34,  // Frame Size = 52
    0x00, 0x00,              // Frame flags
    0x01,                    // Text encoding [UTF-16]
    // MIME type
    'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'c', '2', 'p',
    'a', 0x00,
    // File name [UTF-16LE]
    0xFF, 0xFE, 'f', 0x00, 'o', 0x00, 'o', 0x00, 0x00, 0x00,
    // Content description [UTF-16LE]
    0xFF, 0xFE, 'b', 0x00, 'a', 0x00, 'r', 0x00, 0x00, 0x00,
    // Encapsulated object
    'm', 'a', 'n', 'i', 'f', 'e', 's', 't', ' ', 's', 't', 'o', 'r', 'e'};

constexpr unsigned char kId3TagWithC2paManifestStoreDeprecatedMimeType[] = {
    'I', 'D', '3',           // ID3 file identifier
    0x03, 0x00,              // Version 2.3
    0x00,                    // Flags
    0x00, 0x00, 0x00, 0x4F,  // Tag size = 79 (69 + 10)
    'G', 'E', 'O', 'B',      // Frame ID
    0x00, 0x00, 0x00, 0x45,  // Frame Size = 69
    0x00, 0x00,              // Frame flags
    0x01,                    // Text encoding [UTF-16]
    // MIME type
    'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'x', '-', 'c',
    '2', 'p', 'a', '-', 'm', 'a', 'n', 'i', 'f', 'e', 's', 't', '-', 's', 't',
    'o', 'r', 'e', 0x00,
    // File name [UTF-16LE]
    0xFF, 0xFE, 'f', 0x00, 'o', 0x00, 'o', 0x00, 0x00, 0x00,
    // Content description [UTF-16LE]
    0xFF, 0xFE, 'b', 0x00, 'a', 0x00, 'r', 0x00, 0x00, 0x00,
    // Encapsulated object
    'm', 'a', 'n', 'i', 'f', 'e', 's', 't', ' ', 's', 't', 'o', 'r', 'e'};

TEST(Id3ExtractorTest,
     ExtractManifestStoreFromGeobFrameWithDeprecatedMimeType) {
  std::string mp3_file_contents =
      std::string(reinterpret_cast<const char*>(
                      kId3TagWithC2paManifestStoreDeprecatedMimeType),
                  sizeof(kId3TagWithC2paManifestStoreDeprecatedMimeType));
  riegeli::StringReader<> input(mp3_file_contents);
  Id3Extractor extractor;
  auto result = extractor.ExtractManifestStore(input);
  ASSERT_THAT(result, IsOk());
  EXPECT_THAT(*result, HasSubstr("manifest store"));
}

TEST(Id3ExtractorTest, ExtractManifestStore) {
  std::string mp3_file_contents =
      std::string(reinterpret_cast<const char*>(kId3TagWithC2paManifestStore),
                  sizeof(kId3TagWithC2paManifestStore));
  riegeli::StringReader<> input(mp3_file_contents);
  Id3Extractor extractor;
  auto result = extractor.ExtractManifestStore(input);
  ASSERT_THAT(result, IsOk());
  EXPECT_THAT(*result, HasSubstr("manifest store"));
}

TEST(Id3ExtractorTest,
     ExtractManifestStoreThrowsErrorIfMultipleC2paManifestStoresFound) {
  std::string mp3_file_contents = std::string(
      reinterpret_cast<const char*>(kId3TagWithMultipleC2paManifestStores),
      sizeof(kId3TagWithMultipleC2paManifestStores));
  riegeli::StringReader<> input(mp3_file_contents);
  Id3Extractor extractor;

  EXPECT_THAT(extractor.ExtractManifestStore(input),
              StatusIs(absl::StatusCode::kNotFound,
                       HasSubstr("Multiple manifest stores found")));
}

TEST(Id3ExtractorTest, ExtractManifestStoreLocation) {
  std::string mp3_file_contents =
      std::string(reinterpret_cast<const char*>(kId3TagWithC2paManifestStore),
                  sizeof(kId3TagWithC2paManifestStore));
  riegeli::StringReader<> input(mp3_file_contents);
  Id3Extractor extractor;
  ASSERT_OK_AND_ASSIGN(
      auto manifest_store_location,
      extractor.ExtractManifestStoreLocation(input, {.requires_c2pa = true}));

  EXPECT_THAT(manifest_store_location,
              Optional(AllOf(Field(&ByteRange::offset, Eq(58)),
                             Field(&ByteRange::length, Eq(14)))));
}

TEST(Id3ExtractorTest, ExtractBoxesUnimplemented) {
  riegeli::StringReader<> input("test_content");
  Id3Extractor extractor;
  EXPECT_THAT(extractor.ExtractBoxes(input, {.requires_c2pa = true}),
              StatusIs(absl::StatusCode::kUnimplemented));
}

}  // namespace
}  // namespace credentio
