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

#include <cstdint>

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

namespace credentio {
namespace {

// The first 5 bytes of an ID3 v2.3 tag header in uint64_t format.
constexpr uint64_t kId3v23Header =
    ((uint64_t)kId3FileIdentifierAndVersionV23[0] << 32) |
    ((uint64_t)kId3FileIdentifierAndVersionV23[1] << 24) |
    ((uint64_t)kId3FileIdentifierAndVersionV23[2] << 16) |
    ((uint64_t)kId3FileIdentifierAndVersionV23[3] << 8) |
    ((uint64_t)kId3FileIdentifierAndVersionV23[4]);

// The first 5 bytes of an ID3 v2.4 tag header in uint64_t format.
constexpr uint64_t kId3v24Header =
    ((uint64_t)kId3FileIdentifierAndVersionV24[0] << 32) |
    ((uint64_t)kId3FileIdentifierAndVersionV24[1] << 24) |
    ((uint64_t)kId3FileIdentifierAndVersionV24[2] << 16) |
    ((uint64_t)kId3FileIdentifierAndVersionV24[3] << 8) |
    ((uint64_t)kId3FileIdentifierAndVersionV24[4]);

// The first 2 bytes of an MPEG Version 2 Layer 3 frame header, with CRC
// protection enabled.
constexpr uint64_t kMp3MpegFrameHeader = 0xFFF3ULL;

// The FLAC stream marker "fLaC".
constexpr uint32_t kFlacMarker = 0x664C6143;

// Returns true if the `header` starts with the ID3 v2.3 or v2.4 identifier.
//
// For a MP3 file that contains ID3 tags, the ID3 tags can be prepended to the
// audio data.
bool StartsWithId3Header(uint64_t header) {
  // Compare the first 5 bytes.
  return (header >> 24) == kId3v23Header || (header >> 24) == kId3v24Header;
}

// Returns true if the `header` starts with a MPEG frame, indicating a MP3 file.
bool StartsWithMp3MpegFrameHeader(uint64_t header) {
  // Compare the first 15 bits, ignoring the protection bit.
  return (header >> 49) == (kMp3MpegFrameHeader >> 1);
}

// Returns true if the `header` starts with FLAC marker.
bool StartsWithFlacMarker(uint64_t header) {
  // Compare the first 4 bytes.
  return (header >> 32) == kFlacMarker;
}
}  // namespace

absl::StatusOr<bool> Id3Assessor::IsSupported(riegeli::Reader& input) const {
  int64_t starting_position = input.pos();

  uint64_t header;
  if (!riegeli::ReadBigEndian<uint64_t>(input, header)) {
    return input.StatusOrAnnotate(absl::DataLossError("kUnexpectedEof"));
  }
  if (!input.Seek(starting_position) || input.pos() != starting_position) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to starting position"));
  }

  return StartsWithId3Header(header) || StartsWithMp3MpegFrameHeader(header) ||
         StartsWithFlacMarker(header);
}
}  // namespace credentio
