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

#include <optional>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "formats/byte_range.h"
#include "formats/id3/constants.h"
#include "formats/id3/id3.h"
#include "formats/id3/reader.h"
#include "jumbf/utils.h"
#include "riegeli/bytes/reader.h"

namespace credentio {
namespace {

struct C2paManifestStore {
  ByteRange location;
  std::string content;
};

bool ContainsC2paManifestStore(const GeobFrame& geob) {
  return geob.mime_type == kGeobFrameMimeType ||
         geob.mime_type == kGeobFrameMimeTypeDeprecated;
}

absl::StatusOr<C2paManifestStore> ExtractManifestStoreInternal(
    riegeli::Reader& input) {
  C2paManifestStore manifest_store;

  auto status = IterateOverId3Frames(
      input, [&](const Id3Frame& frame) -> absl::StatusOr<bool> {
        if (frame.id == "GEOB") {
          ABSL_ASSIGN_OR_RETURN(const GeobFrame geob,
                                GeobFrame::Parse(input, frame.data_offset(),
                                                 frame.data_length()));
          if (ContainsC2paManifestStore(geob)) {
            if (!manifest_store.content.empty()) {
              return absl::NotFoundError("Multiple manifest stores found");
            }
            manifest_store.location = {
                .offset = frame.data_offset() + frame.data_length() -
                          geob.encapsulated_object.size(),
                .length = geob.encapsulated_object.size(),
            };
            manifest_store.content = std::move(geob.encapsulated_object);
          }
        }
        return true;
      });

  if (absl::IsNotFound(status.status())) {
    if (status.status().message() != "Multiple manifest stores found") {
      return absl::NotFoundError("No manifest store found");
    }
    return status.status();
  }
  if (!status.ok()) {
    return status.status();
  }

  if (manifest_store.content.empty()) {
    return absl::NotFoundError("No manifest store found");
  }
  return manifest_store;
}
}  // namespace

absl::StatusOr<std::string> Id3Extractor::ExtractManifestStore(
    riegeli::Reader& input) const {
  ABSL_ASSIGN_OR_RETURN(auto manifest_store,
                        ExtractManifestStoreInternal(input));
  return manifest_store.content;
}

absl::StatusOr<std::optional<ByteRange>>
Id3Extractor::ExtractManifestStoreLocation(riegeli::Reader& input,
                                           ExtractOptions options) const {
  auto manifest_store = ExtractManifestStoreInternal(input);

  if (!manifest_store.ok()) {
    if (options.requires_c2pa) {
      return manifest_store.status();
    }
    return std::nullopt;
  }
  return manifest_store->location;
}

bool Id3Extractor::MightBeC2paManifestStore(absl::string_view payload) const {
  return jumbf::HasDescriptionBoxMatching(payload, kManifestStoreUuid,
                                          kMinimumJumbfDescriptionToggles,
                                          kManifestStoreLabel)
      .value_or(false);
}
}  // namespace credentio
