// 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_GENERATOR_H_
#define THIRD_PARTY_CREDENTIO_CLAIM_GENERATOR_H_

#include <memory>

#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
#include "assertion/assertion_cbor_encoder.h"
#include "async/async_context.h"
#include "claim/claim_cbor_encoder.h"
#include "claim/manifest_box.h"
#include "claim/manifest_box_assembler.h"
#include "claim/manifest_box_encoder.h"
#include "claim/signer.h"
#include "constants/spec_version.h"
#include "crypto/hash.h"
#include "proto/generator.pb.h"
#include "proto/generator_info.pb.h"
#include "proto/manifest.pb.h"
#include "salt/salt_generator.h"
#include "uuid/uuid.h"

namespace credentio {

// An abstract class to serialize a Manifest in JUMBF format as a Manifest
// Store SuperBox.
class ManifestEncoder {
 public:
  virtual ~ManifestEncoder() = default;
  // Encodes the given Manifest to a JUMBF-type box. The manifest will be
  // wrapped in a Manifest Store SuperBox. Consumes the provided ManifestBox,
  // which must outlive the task.
  virtual void Encode(
      ManifestBox* absl_nonnull manifest,
      const GenerateManifestStoreOptions& options, AsyncContext context,
      absl::AnyInvocable<void(absl::StatusOr<ManifestEncoderResult>) &&> cb)
      const = 0;
};

struct CreateManifestAssemblerOptions {
  // Required.
  const UuidGenerator* absl_nonnull uuid_generator;
  // Required.
  const HasherFactory* absl_nonnull hash_factory;
  // The C2PA specification version the generated manifests conform to.
  SpecVersion spec_version = SpecVersion::kC2pa_2_2;
};

using ManifestAssemblerFactory =
    absl::AnyInvocable<absl::StatusOr<std::unique_ptr<ManifestBoxAssembler>>(
        const CreateManifestAssemblerOptions& options) const>;

absl::StatusOr<std::unique_ptr<ManifestBoxAssembler>> CreateManifestAssembler(
    const CreateManifestAssemblerOptions& options);

struct CreateManifestEncoderOptions {
  // Required.
  GeneratorInfo generator_info;
  // Required.
  ClaimSigner* absl_nonnull claim_signer;
  // Required.
  const AssertionCborEncoder* absl_nonnull assertion_cbor_encoder;
  // Required.
  const ClaimCborEncoder* absl_nonnull claim_cbor_encoder;
  // Required.
  const HasherFactory* absl_nonnull hash_factory;
  // Required. Salts every assertion; use `SaltGenerator::NoOp()` to disable
  // salting. Must outlive the created encoder.
  const SaltGenerator* absl_nonnull salt_generator;
};

absl::StatusOr<std::unique_ptr<ManifestEncoder>> CreateManifestEncoder(
    const CreateManifestEncoderOptions& options);
}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_CLAIM_GENERATOR_H_
