// 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::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::Field;
using ::testing::HasSubstr;
using ::testing::Optional;

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);
  ABSL_ASSERT_OK(result);
  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);
  ABSL_ASSERT_OK(result);
  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;
  EXPECT_THAT(
      extractor.ExtractManifestStoreLocation(input, {.requires_c2pa = true}),
      IsOkAndHolds(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
