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

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

#include "absl/base/nullability.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "crypto/algorithms.h"
#include "formats/zip/embedder.h"
#include "formats/zip/hasher_data.h"
#include "formats/zip/reader.h"
#include "proto/generator.pb.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/writer.h"

namespace credentio {

absl::Status ZipWriter::Write(GenerateManifestStoreRequest& request,
                              riegeli::Reader* absl_nonnull source,
                              riegeli::Writer* absl_nonnull destination) {
  if (request.has_hard_binding()) {
    return absl::InvalidArgumentError(
        "request must not include `hard_binding` (binding is computed by "
        "ZipWriter)");
  }

  ABSL_ASSIGN_OR_RETURN(auto reader, ZipReader::Create(source));

  std::vector<ZipReader::FileEntry> file_entries;
  while (reader->HasNext()) {
    ABSL_ASSIGN_OR_RETURN(auto entry, reader->Next());
    file_entries.push_back(entry);
  }

  // The two-phase approach is required for ZIP-based assets: The sections to be
  // hashed can't be finalized until the manifest store size is known and
  // content types stream is updated.

  // Phase 1: Copy the asset to the destination, update the content types
  // stream, compute preliminary hard binding, produce a manifest store
  // template, and embed a zero-filled placeholder in the asset.
  HashAlgorithm alg = HashAlgorithm::kSha256;
  ABSL_ASSIGN_OR_RETURN(
      *request.mutable_hard_binding()->mutable_collection_data_hash(),
      CollectionDataHashTemplate(file_entries, alg));
  ABSL_ASSIGN_OR_RETURN(ManifestStoreTemplate manifest_store_template,
                        generator_.GenerateManifestStoreTemplate(request));
  constexpr int64_t kMaxManifestStoreSizeBytes = 100 * 1024 * 1024;  // 100 MiB
  if (manifest_store_template.manifest_store_size() <= 0 ||
      manifest_store_template.manifest_store_size() >
          kMaxManifestStoreSizeBytes) {
    return absl::InvalidArgumentError(
        absl::StrCat("invalid manifest store template size: ",
                     manifest_store_template.manifest_store_size()));
  }

  ZipEmbedder embedder;
  ABSL_ASSIGN_OR_RETURN(
      auto copy_and_allocate_result,
      embedder.CopyAndAllocate(source, file_entries,
                               manifest_store_template.manifest_store_size(),
                               destination));

  // Phase 2: Compute final hard binding based on the updated content, finalize
  // the manifest store, and embed the final manifest store in the asset.
  if (!destination->SupportsReadMode()) {
    return absl::InvalidArgumentError(
        "ZipWriter::Write requires a riegeli::Writer that supports read mode.");
  }
  riegeli::Reader* phase2_reader = destination->ReadMode(0);
  if (phase2_reader == nullptr) {
    return absl::InternalError("failed to switch to read mode");
  }

  ABSL_ASSIGN_OR_RETURN(auto phase2_zip_reader,
                        ZipReader::Create(phase2_reader));
  std::vector<ZipReader::FileEntry> phase2_file_entries;
  while (phase2_zip_reader->HasNext()) {
    ABSL_ASSIGN_OR_RETURN(auto entry, phase2_zip_reader->Next());
    phase2_file_entries.push_back(entry);
  }
  FinalizeManifestStoreRequest finalize_request;
  *finalize_request.mutable_manifest_store_template() =
      std::move(manifest_store_template);
  ABSL_ASSIGN_OR_RETURN(
      *finalize_request.mutable_hard_binding()->mutable_collection_data_hash(),
      DigestCollectionDataHash(
          phase2_reader, alg, phase2_file_entries,
          copy_and_allocate_result.central_directory_offset));
  ABSL_ASSIGN_OR_RETURN(auto response,
                        generator_.FinalizeManifestStore(finalize_request));
  if (response.manifest_store().size() !=
      finalize_request.manifest_store_template().manifest_store_size()) {
    return absl::InternalError("manifest store size does not match template");
  }
  ABSL_RETURN_IF_ERROR(embedder.Embed(response.manifest_store(),
                                      copy_and_allocate_result, destination));
  return absl::OkStatus();
}

}  // namespace credentio
