// 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 <sys/types.h>

#include <cstdint>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "formats/id3/id3.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/endian/endian_reading.h"

namespace credentio {

constexpr uint32_t kId3TagHeaderSize = 10;
constexpr uint32_t kId3FrameHeaderSize = 10;

absl::StatusOr<Id3Header> IterateOverId3Frames(riegeli::Reader& reader,
                                               Id3FrameProcessor processor) {
  if (!reader.SupportsSize() || !reader.Size().has_value()) {
    return absl::InvalidArgumentError("reader does not support size");
  }

  uint64_t beginning_offset = reader.pos();
  ABSL_ASSIGN_OR_RETURN(Id3Header id3_header, Id3Header::Parse(reader));
  uint64_t id3_tag_end_offset =
      beginning_offset + kId3TagHeaderSize + id3_header.tag_size;

  if (id3_tag_end_offset > reader.Size().value()) {
    return absl::InvalidArgumentError("tag end offset exceeds input size");
  }

  uint64_t current_offset = reader.pos();

  while (current_offset + kId3FrameHeaderSize < id3_tag_end_offset) {
    // Peek the next frame ID to see if the ID is valid.
    uint32_t frame_id;
    if (!reader.Seek(current_offset)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to seek to current offset"));
    }
    if (!riegeli::ReadBigEndian<uint32_t>(reader, frame_id)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to read frame ID for peeking"));
    }

    // Check if the frame ID is all NULL bytes. This indicates the start of
    // padding at the end of the ID3v2 tag.
    if (frame_id == 0) {
      break;
    }

    if (!reader.Seek(current_offset)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to seek back to current offset"));
    }

    Id3Frame frame;
    frame.offset = current_offset;
    // Read the ID3 frame header, which is 10 bytes.
    if (!reader.Read(4, frame.id)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to read frame ID"));
    }
    uint32_t size;
    if (!riegeli::ReadBigEndian<uint32_t>(reader, size)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to read frame size"));
    }
    if (id3_header.major_version == 4) {
      if ((size & 0x80808080) != 0) {
        return reader.StatusOrAnnotate(absl::DataLossError(
            "Invalid synchsafe integer in ID3v2.4 frame size"));
      }
      size = ((size >> 24) & 0x7f) << 21 | ((size >> 16) & 0x7f) << 14 |
             ((size >> 8) & 0x7f) << 7 | (size & 0x7f);
    }
    std::string flags;
    if (!reader.Read(2, flags)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to read frame flags"));
    }
    const uint64_t remaining_tag_size =
        id3_tag_end_offset - current_offset - kId3FrameHeaderSize;
    if (size > remaining_tag_size) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("ID3 frame size exceeds remaining tag size"));
    }

    frame.length = static_cast<uint64_t>(size) + kId3FrameHeaderSize;

    ABSL_ASSIGN_OR_RETURN(bool continue_iteration, processor(frame));
    if (!continue_iteration) {
      break;
    }

    // Seek to the end of the frame for the next iteration.
    if (!reader.Seek(frame.offset + frame.length)) {
      return reader.StatusOrAnnotate(
          absl::DataLossError("Failed to seek to end of frame"));
    }
    current_offset = reader.pos();
  }

  return id3_header;
}

}  // namespace credentio
