// 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/embedder.h"

#include <string>

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

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::Eq;
using ::testing::HasSubstr;

// Simple MPEG-2 Layer 3 frame header followed by 4 bytes of dummy data.
constexpr char kMp3FileWithNoId3Tag[] = {'\xFF', '\xF3', '\x40', '\xC0',
                                         0x01,   0x02,   0x03,   0x04};

constexpr char kMp3FileWithNoC2paFrame[] = {
    'I', 'D', '3', '\x03', '\x00', '\x00', '\x00', '\x00', '\x00',
    '\x0F',  // Tag size = 15
    // A 15-byte COMM frame
    'C', 'O', 'M', 'M', '\x00', '\x00', '\x00', '\x05', '\x00', '\x00', '\x00',
    '\x00', '\x00', '\x00', '\x00'};

constexpr char kMp3FileWithId3v24NoC2paFrame[] = {
    'I', 'D', '3', '\x04', '\x00', '\x00', '\x00', '\x00', '\x00',
    '\x0F',  // Tag size = 15
    // A 15-byte COMM frame
    'C', 'O', 'M', 'M', '\x00', '\x00', '\x00', '\x05', '\x00', '\x00', '\x00',
    '\x00', '\x00', '\x00', '\x00'};

constexpr char kMp3FileWithNoC2paFrameWithExtendedHeader[] = {
    'I', 'D', '3',           // ID3 file identifier
    0x03, 0x00,              // Version 2.3
    0x40,                    // Flags (bit 6 indicates extended header)
    0x00, 0x00, 0x00, 0x19,  // Tag size = 25
    // Extended header
    0x00, 0x00, 0x00, 0x06,  // Extended header size = 6
    0x00, 0x00,              // Extended flags
    0x00, 0x00, 0x00, 0x00,  // Size of padding
    // A 15-byte COMM frame
    'C', 'O', 'M', 'M', 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00};

constexpr char kMp3FileWithC2paManifestStore[] = {
    '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]
    '\xFF', '\xFE', 'f', 0x00, 'o', 0x00, 'o', 0x00, 0x00, 0x00,
    // Content description [UTF-16LE]
    '\xFF', '\xFE', 'b', 0x00, 'a', 0x00, 'r', 0x00, 0x00, 0x00,
    // Encapsulated object
    'm', 'a', 'n', 'i', 'f', 'e', 's', 't', ' ', 's', 't', 'o', 'r', 'e'};

TEST(Id3EmbedderTest, CopyAndEmbedNoId3Tag) {
  std::string mp3_file_contents =
      std::string(kMp3FileWithNoId3Tag, sizeof(kMp3FileWithNoId3Tag));
  absl::string_view kManifestStore = "C2PA manifest store bytes";
  riegeli::StringReader<> input(mp3_file_contents);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);

  Id3Embedder embedder;
  auto manifest_store_offset =
      embedder.CopyAndEmbed(input, kManifestStore, output);
  ABSL_ASSERT_OK(manifest_store_offset.status());
  ASSERT_TRUE(output.Close());

  EXPECT_THAT(output_s.substr(*manifest_store_offset, kManifestStore.size()),
              Eq(kManifestStore));

  Id3Extractor extractor;
  riegeli::StringReader<> output_reader(output_s);
  EXPECT_THAT(extractor.ExtractManifestStore(output_reader),
              IsOkAndHolds(kManifestStore));
}

TEST(Id3EmbedderTest, CopyAndEmbedNoC2paFrame) {
  std::string mp3_file_contents =
      std::string(kMp3FileWithNoC2paFrame, sizeof(kMp3FileWithNoC2paFrame));
  absl::string_view kManifestStore = "C2PA manifest store bytes";
  riegeli::StringReader input(mp3_file_contents);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);

  Id3Embedder embedder;
  auto manifest_store_offset =
      embedder.CopyAndEmbed(input, kManifestStore, output);
  ABSL_ASSERT_OK(manifest_store_offset.status());
  ASSERT_TRUE(output.Close());

  EXPECT_THAT(output_s.substr(*manifest_store_offset, kManifestStore.size()),
              Eq(kManifestStore));

  Id3Extractor extractor;
  riegeli::StringReader<> output_reader(output_s);
  EXPECT_THAT(extractor.ExtractManifestStore(output_reader),
              IsOkAndHolds(kManifestStore));
}

TEST(Id3EmbedderTest, CopyAndEmbedNoC2paFrameWithExtendedHeader) {
  std::string mp3_file_contents =
      std::string(kMp3FileWithNoC2paFrameWithExtendedHeader,
                  sizeof(kMp3FileWithNoC2paFrameWithExtendedHeader));
  absl::string_view kManifestStore = "C2PA manifest store bytes";
  riegeli::StringReader input(mp3_file_contents);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);

  Id3Embedder embedder;
  auto manifest_store_offset =
      embedder.CopyAndEmbed(input, kManifestStore, output);
  ABSL_ASSERT_OK(manifest_store_offset.status());
  ASSERT_TRUE(output.Close());

  EXPECT_THAT(output_s.substr(*manifest_store_offset, kManifestStore.size()),
              Eq(kManifestStore));

  Id3Extractor extractor;
  riegeli::StringReader<> output_reader(output_s);
  EXPECT_THAT(extractor.ExtractManifestStore(output_reader),
              IsOkAndHolds(kManifestStore));
}

TEST(Id3EmbedderTest, CopyAndEmbedId3v24SynchsafeFrameSize) {
  std::string mp3_file_contents = std::string(
      kMp3FileWithId3v24NoC2paFrame, sizeof(kMp3FileWithId3v24NoC2paFrame));
  std::string manifest_store(300, 'a');
  riegeli::StringReader input(mp3_file_contents);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);

  Id3Embedder embedder;
  auto manifest_store_offset =
      embedder.CopyAndEmbed(input, manifest_store, output);
  ABSL_ASSERT_OK(manifest_store_offset.status());
  ASSERT_TRUE(output.Close());

  EXPECT_THAT(output_s.substr(*manifest_store_offset, manifest_store.size()),
              Eq(manifest_store));

  Id3Extractor extractor;
  riegeli::StringReader<> output_reader(output_s);
  EXPECT_THAT(extractor.ExtractManifestStore(output_reader),
              IsOkAndHolds(manifest_store));
}

TEST(Id3EmbedderTest, CopyAndEmbedC2paAlreadyExists) {
  std::string mp3_file_contents = std::string(
      kMp3FileWithC2paManifestStore, sizeof(kMp3FileWithC2paManifestStore));
  absl::string_view kManifestStore = "C2PA manifest store bytes";
  riegeli::StringReader input(mp3_file_contents);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);

  Id3Embedder embedder;
  EXPECT_THAT(embedder.CopyAndEmbed(input, kManifestStore, output),
              StatusIs(absl::StatusCode::kAlreadyExists,
                       HasSubstr("C2PA manifest store already exists")));
}

}  // namespace
}  // namespace credentio
