// 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;
  });
  ABSL_ASSERT_OK(status);
  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
