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

#include <cstdint>
#include <memory>
#include <optional>
#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 "constants/labels.h"
#include "formats/byte_range.h"
#include "formats/zip/constants.h"
#include "formats/zip/reader.h"
#include "jumbf/utils.h"
#include "riegeli/base/types.h"
#include "riegeli/bytes/reader.h"

namespace credentio {
namespace {

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

absl::StatusOr<C2paManifestStore> ExtractManifestStoreInternal(
    riegeli::Reader& input) {
  ABSL_ASSIGN_OR_RETURN(std::unique_ptr<ZipReader> reader,
                        ZipReader::Create(&input));

  C2paManifestStore manifest_store;
  while (reader->HasNext()) {
    ABSL_ASSIGN_OR_RETURN(ZipReader::FileEntry entry, reader->Next());
    if (entry.file_name == kZipManifestFileName) {
      if (!manifest_store.content.empty()) {
        return absl::NotFoundError("Multiple manifest stores found");
      }
      if (entry.compression_method != 0) {
        return absl::InvalidArgumentError(
            "Manifest store must not be compressed.");
      }
      manifest_store.location = entry.file_range;
      // Manifest store is typically up to a few MBs (usually under 16 MB).
      constexpr uint64_t kMaxManifestStoreSize = 16 * 1024 * 1024;
      if (manifest_store.location.length > kMaxManifestStoreSize ||
          entry.uncompressed_size > kMaxManifestStoreSize) {
        return absl::InvalidArgumentError(
            "Manifest store size exceeds maximum limit.");
      }
      std::optional<riegeli::Position> source_size = input.Size();
      if (source_size.has_value() &&
          manifest_store.location.length > *source_size) {
        return absl::InvalidArgumentError(
            "Manifest store length exceeds source size.");
      }
      if (!input.Seek(entry.file_range.offset) ||
          input.pos() != entry.file_range.offset) {
        return absl::InvalidArgumentError(
            "The input could not be reset to the manifest store location.");
      }
      if (!input.Read(manifest_store.location.length, manifest_store.content)) {
        return input.StatusOrAnnotate(
            absl::InternalError("Failed to read manifest store"));
      }
    }
  }
  if (manifest_store.content.empty()) {
    return absl::NotFoundError("No manifest store found");
  }
  return manifest_store;
}
}  // namespace

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

absl::StatusOr<std::optional<ByteRange>>
ZipExtractor::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 ZipExtractor::MightBeC2paManifestStore(absl::string_view payload) const {
  return jumbf::HasDescriptionBoxMatching(payload, kManifestStoreUuid,
                                          kMinimumJumbfDescriptionToggles,
                                          kManifestStoreLabel)
      .value_or(false);
}

}  // namespace credentio
