// 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 <cstdint>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "formats/id3/constants.h"
#include "formats/id3/id3.h"
#include "formats/id3/reader.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/writer.h"

namespace credentio {
namespace {

// The size of the ID3 header excluded from the ID3 tag size calculation.
constexpr uint32_t kExcludedId3TagHeaderSize = 10;
// The size of the ID3 extended header excluded from the ID3 extended header
// size calculation.
constexpr uint32_t kExcludedId3ExtendedHeaderSize = 4;

constexpr absl::string_view kGeobFrameFileName = "c2pa";
constexpr absl::string_view kGeobFrameContentDescription =
    "c2pa manifest store";

// Encodes the C2PA manifest store as an ID3 GEOB frame, returns the encoded
// frame as an `absl::Cord`. ID3v2.4 frame sizes are encoded as synchsafe
// integers, whereas ID3v2.3 frame sizes are 32-bit big-endian integers.
absl::StatusOr<absl::Cord> EncodeManifestStoreAsId3Frame(
    absl::string_view manifest_store, uint8_t major_version) {
  absl::Cord geob_frame_data;
  // Encode manifest store as the GEOB frame data.
  geob_frame_data.Append(
      absl::string_view("\x00", 1));           // Text encoding [ISO-8859-1]
  geob_frame_data.Append(kGeobFrameMimeType);  // MIME type
  geob_frame_data.Append(absl::string_view("\x00", 1));  // NULL terminator
  geob_frame_data.Append(kGeobFrameFileName);            // File name
  geob_frame_data.Append(absl::string_view("\x00", 1));  // NULL terminator
  geob_frame_data.Append(kGeobFrameContentDescription);  // Content description
  geob_frame_data.Append(absl::string_view("\x00", 1));  // NULL terminator
  geob_frame_data.Append(manifest_store);  // Manifest store as encapsulated
                                           // object

  absl::Cord output;
  // Write the GEOB frame header.
  output.Append(absl::string_view("GEOB", 4));
  uint32_t frame_size = geob_frame_data.size();
  char size_bytes[4];
  if (major_version == 4) {
    if (frame_size > 0x0FFFFFFF) {
      return absl::InvalidArgumentError(
          "Frame size exceeds maximum allowable ID3v2.4 frame size");
    }
    // Encode the frame size as a synchsafe integer.
    size_bytes[0] = (frame_size >> 21) & 0x7F;
    size_bytes[1] = (frame_size >> 14) & 0x7F;
    size_bytes[2] = (frame_size >> 7) & 0x7F;
    size_bytes[3] = frame_size & 0x7F;
  } else {  // ID3v2.3
    size_bytes[0] = (frame_size >> 24) & 0xFF;
    size_bytes[1] = (frame_size >> 16) & 0xFF;
    size_bytes[2] = (frame_size >> 8) & 0xFF;
    size_bytes[3] = frame_size & 0xFF;
  }
  output.Append(absl::string_view(size_bytes, 4));
  output.Append(absl::string_view("\x00\x00", 2));  // Flags
  // Append the GEOB frame data.
  output.Append(std::move(geob_frame_data));

  return output;
}

}  // namespace

absl::StatusOr<int64_t> Id3Embedder::CopyAndEmbed(
    riegeli::Reader& input, absl::string_view manifest_store,
    riegeli::Writer& output) const {
  if (!input.SupportsSize() || !input.Size().has_value()) {
    return absl::InvalidArgumentError("input does not support size");
  }
  uint64_t asset_size = input.Size().value();

  int64_t beginning_offset = input.pos();
  auto status = IterateOverId3Frames(
      input, [&](const Id3Frame& frame) -> absl::StatusOr<bool> {
        if (frame.id == "GEOB") {
          ABSL_ASSIGN_OR_RETURN(auto geob_frame,
                                GeobFrame::Parse(input, frame.data_offset(),
                                                 frame.data_length()));
          if (geob_frame.mime_type == kGeobFrameMimeType ||
              geob_frame.mime_type == kGeobFrameMimeTypeDeprecated) {
            return absl::AlreadyExistsError(
                "C2PA manifest store already exists.");
          }
        }
        return true;
      });

  if (absl::IsNotFound(status.status())) {
    // No ID3v2 tag found in the input audio file, so we prepend a simplest ID3
    // tag with only one GEOB frame for the manifest store.
    ABSL_ASSIGN_OR_RETURN(
        absl::Cord manifest_store_frame_encoded,
        EncodeManifestStoreAsId3Frame(manifest_store, /*major_version=*/3));
    Id3Header id3_header = {
        .use_unsynchronisation = false,
        .has_extended_header = false,
        .is_experimental = false,
        .tag_size = static_cast<uint32_t>(manifest_store_frame_encoded.size()),
    };

    if (!output.Write(id3_header.ToCord())) {
      return output.StatusOrAnnotate(
          absl::InternalError("failed to write ID3 header"));
    }
    if (!output.Write(manifest_store_frame_encoded)) {
      return output.StatusOrAnnotate(
          absl::InternalError("failed to write manifest store frame"));
    }
    int64_t manifest_store_offset = output.pos() - manifest_store.size();

    if (!input.Seek(beginning_offset)) {
      return input.StatusOrAnnotate(
          absl::InternalError("failed to seek to start of input"));
    }
    if (!input.Copy(asset_size - beginning_offset, output)) {
      return input.StatusOrAnnotate(
          absl::InternalError("failed to copy input"));
    }
    return manifest_store_offset;
  }
  if (!status.ok()) {
    // Propagate other errors during reader creation.
    return status.status();
  }

  Id3Header id3_header = status.value();
  uint32_t id3_header_size =
      kExcludedId3TagHeaderSize +
      (id3_header.has_extended_header
           ? kExcludedId3ExtendedHeaderSize + id3_header.extended_header_size
           : 0);
  ABSL_ASSIGN_OR_RETURN(
      absl::Cord manifest_store_frame,
      EncodeManifestStoreAsId3Frame(manifest_store, id3_header.major_version));
  // Update the tag size to include the new manifest store frame.
  if (static_cast<uint64_t>(id3_header.tag_size) + manifest_store_frame.size() >
      0x0FFFFFFF) {
    return absl::InvalidArgumentError(
        "Tag size exceeds maximum allowable ID3 tag size");
  }
  id3_header.tag_size += static_cast<uint32_t>(manifest_store_frame.size());

  if (!output.Write(id3_header.ToCord())) {
    return output.StatusOrAnnotate(
        absl::InternalError("failed to write ID3 header"));
  }
  if (!output.Write(manifest_store_frame)) {
    return output.StatusOrAnnotate(
        absl::InternalError("failed to write manifest store frame"));
  }

  int64_t manifest_store_offset = output.pos() - manifest_store.size();
  // Copy the rest of the input audio file.
  if (!input.Seek(beginning_offset + id3_header_size)) {
    return input.StatusOrAnnotate(
        absl::InternalError("failed to seek to start of input"));
  }
  if (!input.Copy(asset_size - id3_header_size, output)) {
    return input.StatusOrAnnotate(absl::InternalError("failed to copy input"));
  }
  return manifest_store_offset;
}
}  // namespace credentio
