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

#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "formats/id3/id3.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::HasSubstr;

TEST(Id3ReaderTest, TagEndOffsetExceedsInputSize) {
  constexpr char mp3_data[] = {'I',    'D',    '3',    '\x03', '\x00',
                               '\x00', '\x7f', '\x7f', '\x7f', '\x7f'};
  auto mp3_file_contents = std::string(mp3_data, sizeof(mp3_data));
  riegeli::StringReader<> input(mp3_file_contents);

  EXPECT_THAT(IterateOverId3Frames(input, [](const Id3Frame&) { return true; }),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("tag end offset exceeds input size")));
}

class NonSizeSupportingStringReader : public riegeli::StringReader<> {
 public:
  using riegeli::StringReader<>::StringReader;
  bool SupportsSize() override { return false; }
};

TEST(Id3ReaderTest, ReaderDoesNotSupportSize) {
  NonSizeSupportingStringReader non_size_input("dummy data");

  EXPECT_THAT(IterateOverId3Frames(non_size_input,
                                   [](const Id3Frame&) { return true; }),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("reader does not support size")));
}

TEST(Id3ReaderTest, EarlyExit) {
  constexpr char mp3_data[] = {
      'I', 'D', '3', '\x03', '\x00', '\x40', '\x00', '\x00', '\x00',
      '\x2c',                          // Tag size = 44
      '\x00', '\x00', '\x00', '\x0a',  // Extended header size = 10
      '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
      '\x00',
      // A 15-byte COMM frame
      'C', 'O', 'M', 'M', '\x00', '\x00', '\x00', '\x05', '\x00', '\x00',
      '\x01', '\x02', '\x03', '\x04', '\x05',
      // A 15-byte GEOB frame
      'G', 'E', 'O', 'B', '\x00', '\x00', '\x00', '\x05', '\x00', '\x00',
      '\x05', '\x04', '\x03', '\x02', '\x01'};
  auto mp3_file_contents = std::string(mp3_data, sizeof(mp3_data));
  riegeli::StringReader<> input(mp3_file_contents);

  std::vector<Id3Frame> frames;
  EXPECT_THAT(IterateOverId3Frames(input,
                                   [&](const Id3Frame& frame) {
                                     frames.push_back(frame);
                                     return false;
                                   }),
              IsOk());

  EXPECT_THAT(frames, testing::ElementsAre(Id3Frame{
                          .offset = 24,
                          .length = 15,
                          .id = "COMM",
                      }));
}

TEST(Id3ReaderTest, ReadsAllFrames) {
  constexpr char mp3_data[] = {
      'I', 'D', '3', '\x03', '\x00', '\x40', '\x00', '\x00', '\x00',
      '\x2c',                          // Tag size = 44
      '\x00', '\x00', '\x00', '\x0a',  // Extended header size = 10
      '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
      '\x00',
      // A 15-byte COMM frame
      'C', 'O', 'M', 'M', '\x00', '\x00', '\x00', '\x05', '\x00', '\x00',
      '\x01', '\x02', '\x03', '\x04', '\x05',
      // A 15-byte GEOB frame
      'G', 'E', 'O', 'B', '\x00', '\x00', '\x00', '\x05', '\x00', '\x00',
      '\x05', '\x04', '\x03', '\x02', '\x01'};
  auto mp3_file_contents = std::string(mp3_data, sizeof(mp3_data));
  riegeli::StringReader<> input(mp3_file_contents);

  std::vector<Id3Frame> frames;
  auto status = IterateOverId3Frames(input, [&](const Id3Frame& frame) {
    frames.push_back(frame);
    return true;
  });
  ASSERT_THAT(status, IsOk());
  ASSERT_TRUE(status.value().has_extended_header);

  EXPECT_THAT(frames, testing::UnorderedElementsAre(
                          Id3Frame{
                              .offset = 24,
                              .length = 15,
                              .id = "COMM",
                          },
                          Id3Frame{
                              .offset = 39,
                              .length = 15,
                              .id = "GEOB",
                          }));
}

TEST(Id3ReaderTest, FrameSizeExceedsRemainingTagSize) {
  constexpr char mp3_data[] = {
      'I', 'D', '3', '\x03', '\x00', '\x40', '\x00', '\x00', '\x00',
      '\x22',                          // Tag size = 34 (syncsafe 0x22)
      '\x00', '\x00', '\x00', '\x0a',  // Extended header size = 10
      '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
      '\x00',
      // Frame: size = 0xFFFFFFF6
      'F', 'I', 'D', 'S', '\xFF', '\xFF', '\xFF', '\xF6', '\x00', '\x00',
      // Padding to satisfy the tag size (10 bytes)
      '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
      '\x00'};
  auto mp3_file_contents = std::string(mp3_data, sizeof(mp3_data));
  riegeli::StringReader<> input(mp3_file_contents);

  int call_count = 0;
  auto status = IterateOverId3Frames(input, [&](const Id3Frame& frame) {
    call_count++;
    return true;
  });

  EXPECT_THAT(status,
              StatusIs(absl::StatusCode::kDataLoss,
                       HasSubstr("ID3 frame size exceeds remaining tag size")));
  EXPECT_EQ(call_count, 0);
}

TEST(Id3ReaderTest, FrameLengthOneTerminates) {
  constexpr char mp3_data[] = {
      'I', 'D', '3', '\x03', '\x00', '\x40', '\x00', '\x00', '\x00',
      '\x22',                          // Tag size = 34
      '\x00', '\x00', '\x00', '\x0a',  // Extended header size = 10
      '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
      '\x00',
      // Frame: size = 0xFFFFFFF7
      'F', 'I', 'D', 'S', '\xFF', '\xFF', '\xFF', '\xF7', '\x00', '\x00',
      // Padding
      '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
      '\x00'};
  auto mp3_file_contents = std::string(mp3_data, sizeof(mp3_data));
  riegeli::StringReader<> input(mp3_file_contents);

  auto status =
      IterateOverId3Frames(input, [](const Id3Frame& frame) { return true; });

  EXPECT_THAT(status,
              StatusIs(absl::StatusCode::kDataLoss,
                       HasSubstr("ID3 frame size exceeds remaining tag size")));
}

}  // namespace
}  // namespace credentio
