// 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_CLAIM_MANIFEST_BOX_ENCODER_H_
#define THIRD_PARTY_CREDENTIO_CLAIM_MANIFEST_BOX_ENCODER_H_

#include <cstddef>
#include <string>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "assertion/assertion_cbor_encoder.h"
#include "assertion/assertion_referencer.h"
#include "claim/claim_cbor_encoder.h"
#include "claim/manifest_box.h"
#include "claim/signer.h"
#include "constants/labels.h"
#include "crypto/algorithms.h"
#include "google/protobuf/repeated_ptr_field.h"
#include "jumbf/box_builder.h"
#include "proto/assertion.pb.h"
#include "proto/generator_info.pb.h"
#include "proto/hashed_uri.pb.h"
#include "proto/multi_asset_hash_assertion.pb.h"
#include "salt/salt_generator.h"

namespace credentio {

struct ManifestEncoderResult {
  // Generated JUMBF manifest store superbox.
  jumbf::BuiltSuperBox box;
};

class ManifestBoxEncoder {
 public:
  ManifestBoxEncoder(
      const AssertionReferencer* absl_nonnull assertion_reference,
      const GeneratorInfo* absl_nonnull generator_info,
      const ClaimSigner* absl_nonnull claim_signer,
      const AssertionCborEncoder* absl_nonnull assertion_cbor_encoder,
      const ClaimCborEncoder* absl_nonnull claim_cbor_encoder,
      ManifestBox* absl_nonnull manifest, HashAlgorithm hash_algorithm,
      const SaltGenerator* absl_nonnull salt_generator)
      : assertion_reference_(*ABSL_DIE_IF_NULL(assertion_reference)),
        generator_info_(*ABSL_DIE_IF_NULL(generator_info)),
        claim_signer_(*ABSL_DIE_IF_NULL(claim_signer)),
        manifest_builder_(kStandardManifestUuid,
                          {.label = absl::Cord(manifest->label)}),
        manifest_(*ABSL_DIE_IF_NULL(manifest)),
        hash_algorithm_(hash_algorithm),
        assertion_cbor_encoder_(*ABSL_DIE_IF_NULL(assertion_cbor_encoder)),
        claim_cbor_encoder_(*ABSL_DIE_IF_NULL(claim_cbor_encoder)),
        salt_generator_(*ABSL_DIE_IF_NULL(salt_generator)) {}

  // Encodes the manifest to a JUMBF-type box.
  // Consumes the provided ManifestBox.
  // Encodings are done in the following order:
  // 1. Build all assertions, resolving references between them.
  // 2. Encode the claim and signature.
  // 3. Encode the assertion store.
  void Encode(
      const ClaimSigner::Options& options,
      absl::AnyInvocable<void(absl::StatusOr<ManifestEncoderResult>) &&> cb);

 private:
  // Encodes the given assertion and adds it to assertion_boxes_,
  // assertion_hashed_uris_, and assertion_url_to_index_. The assertion box is
  // salted with salt_generator_.
  absl::Status AddAssertion(Assertion& assertion);

  // Populates hashes for hashed URIs in the given actions assertion, then adds
  // it via AddAssertion.
  absl::Status AddActionsAssertion(Assertion assertion);

  // Builds all assertions in the manifest and resolves references between
  // them, populating assertion_boxes_, assertion_hashed_uris_, and
  // assertion_url_to_index_.
  absl::Status AddAssertions();

  // Encodes and signs the claim, adding claim and claim signature boxes to
  // manifest_builder_.
  void EncodeClaimAndSignature(
      const ClaimSigner::Options& options,
      absl::AnyInvocable<void(absl::StatusOr<ManifestEncoderResult>) &&> cb);

  // Adds the assertion store box to manifest_builder_.
  absl::Status EncodeAssertionStore();

  // Populates hashed URIs in the given multi-asset hash assertion.
  // Assumes that the referenced part hash assertions have already been added.
  absl::Status PopulateMultiAssetPartHashes(
      MultiAssetHashAssertion* assertion) const;

  // Encodes a gathered assertion as a JSON content superbox, generates its
  // hashed URI, adds the box to assertion_boxes_, and adds the hashed URI to
  // gathered_assertion_hashed_uris_.
  absl::Status AddGatheredAssertion(
      const GatheredAssertion& gathered_assertion);

  const AssertionReferencer& assertion_reference_;
  const GeneratorInfo& generator_info_;
  const ClaimSigner& claim_signer_;
  jumbf::SuperBoxBuilder manifest_builder_;
  ManifestBox& manifest_;
  // Redacted assertions to be added to the claim.
  std::vector<std::string> redacted_assertions_;
  std::vector<jumbf::BuiltSuperBox> assertion_boxes_;
  google::protobuf::RepeatedPtrField<HashedUri> assertion_hashed_uris_;
  google::protobuf::RepeatedPtrField<HashedUri> gathered_assertion_hashed_uris_;
  // Map from relative assertion URL (e.g.
  // "self#jumbf=c2pa.assertions/c2pa.actions.v2") to index in assertion_uris_.
  // Needed for resolving references between assertions.
  absl::flat_hash_map<std::string, size_t> assertion_url_to_index_;
  HashAlgorithm hash_algorithm_;
  const AssertionCborEncoder& assertion_cbor_encoder_;
  const ClaimCborEncoder& claim_cbor_encoder_;
  const SaltGenerator& salt_generator_;
};
}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_CLAIM_MANIFEST_BOX_ENCODER_H_
