// 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.
//

#ifndef THIRD_PARTY_CREDENTIO_FORMATS_ZIP_READER_H_
#define THIRD_PARTY_CREDENTIO_FORMATS_ZIP_READER_H_

#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/base/nullability.h"
#include "absl/status/statusor.h"
#include "absl/types/span.h"
#include "formats/byte_range.h"
#include "riegeli/bytes/reader.h"

namespace credentio {

// Zip Reader for C2PA, holds onto a reference to a `riegeli::Reader` which
// must outlive the reader.
class ZipReader {
 public:
  // Represents a file entry in a ZIP archive, derived from the file header in
  // the central directory.
  struct FileEntry {
    uint64_t central_directory_header_offset = 0;
    uint64_t local_file_header_offset = 0;
    std::string file_name;
    ByteRange file_range;
    bool has_data_descriptor = false;
    uint16_t general_purpose_bit_flag = 0;
    uint16_t compression_method = 0;
    uint32_t uncompressed_size = 0;
    uint16_t extra_field_length = 0;
    uint16_t file_comment_length = 0;

    bool operator==(const FileEntry& other) const {
      return central_directory_header_offset ==
                 other.central_directory_header_offset &&
             local_file_header_offset == other.local_file_header_offset &&
             file_name == other.file_name && file_range == other.file_range &&
             has_data_descriptor == other.has_data_descriptor &&
             general_purpose_bit_flag == other.general_purpose_bit_flag &&
             compression_method == other.compression_method &&
             uncompressed_size == other.uncompressed_size &&
             extra_field_length == other.extra_field_length &&
             file_comment_length == other.file_comment_length;
    }
  };

  static absl::StatusOr<std::unique_ptr<ZipReader>> Create(
      riegeli::Reader* absl_nonnull input ABSL_ATTRIBUTE_LIFETIME_BOUND);

  // Sorts ZIP file entries by header offset and checks that they do not have
  // duplicate offsets or overlapping ranges to prevent ZIP bomb conditions.
  static absl::StatusOr<std::vector<ZipReader::FileEntry>> SortFileEntries(
      absl::Span<const ZipReader::FileEntry> file_entries);

  // Returns the offset of the start of the central directory.
  uint64_t central_directory_offset() const {
    return central_directory_offset_;
  }

  // Returns true if there is a file entry to read.
  bool HasNext() const { return current_it_ < file_entries_.end(); };

  // Reads the next file entry in the ZIP archive. Returns an OUT_OF_RANGE
  // error if there are no more entries to read.
  absl::StatusOr<FileEntry> Next();

 private:
  explicit ZipReader(std::vector<ZipReader::FileEntry>&& file_entries,
                     uint64_t central_directory_offset)
      : file_entries_(std::move(file_entries)),
        current_it_(file_entries_.begin()),
        central_directory_offset_(central_directory_offset) {}

  // All the file entries in the ZIP archive.
  const std::vector<ZipReader::FileEntry> file_entries_;
  std::vector<ZipReader::FileEntry>::const_iterator current_it_;

  uint64_t central_directory_offset_;
};
}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_FORMATS_ZIP_READER_H_
