// 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_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"

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 AssertionEncoder* absl_nonnull assertion_cbor_encoder,
      const ClaimCborEncoder* absl_nonnull claim_cbor_encoder,
      ManifestBox* absl_nonnull manifest, HashAlgorithm hash_algorithm)
      : 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_encoder_(*ABSL_DIE_IF_NULL(assertion_cbor_encoder)),
        claim_cbor_encoder_(*ABSL_DIE_IF_NULL(claim_cbor_encoder)) {}

  // 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_.
  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 AssertionEncoder& assertion_encoder_;
  const ClaimCborEncoder& claim_cbor_encoder_;
};
}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_CLAIM_MANIFEST_BOX_ENCODER_H_
