// 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_GENERATOR_GENERATOR_H_
#define THIRD_PARTY_CREDENTIO_GENERATOR_GENERATOR_H_

#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
#include "async/async_context.h"
#include "proto/generator.pb.h"

namespace credentio {
// A generator for creating a C2PA Manifest Store for an asset.
//
// This is sometimes called the "bare metal" generation API, to distinguish it
// from "container-level" APIs that operate on a complete media file.
class ManifestStoreGenerator {
 public:
  virtual ~ManifestStoreGenerator() = default;
  // Generates a Manifest Store -- a collection of C2PA Manifests -- from the
  // given request according to the C2PA specification, and returns the encoded
  // bytes that can be embedded into an asset (e.g., an image, a video, etc.).
  // The request must include a hard binding assertion.
  virtual void GenerateManifestStore(
      GenerateManifestStoreRequest request, AsyncContext context,
      absl::AnyInvocable<void(absl::StatusOr<GenerateManifestStoreResponse>) &&>
          cb) const = 0;
  // Blocking version.
  absl::StatusOr<GenerateManifestStoreResponse> GenerateManifestStore(
      GenerateManifestStoreRequest request) const;

  // Generates a Manifest Store template for allocating space for the C2PA
  // data. The request must include a hard binding assertion. Within the hard
  // binding, the following may be placeholders (zero):
  //   - hash values
  //   - data hash exclusion byte offsets and lengths
  //   - multi-asset part location byte offsets and lengths
  // Caller must provide the fully populated binding to FinalizeManifestStore
  // once the asset is constructed (except for the manifest store).
  virtual void GenerateManifestStoreTemplate(
      GenerateManifestStoreRequest request, AsyncContext context,
      absl::AnyInvocable<void(absl::StatusOr<ManifestStoreTemplate>) &&> cb)
      const = 0;
  // Blocking version.
  absl::StatusOr<ManifestStoreTemplate> GenerateManifestStoreTemplate(
      GenerateManifestStoreRequest request) const;

  // Finalizes and returns the serialized manifest store.
  virtual void FinalizeManifestStore(
      FinalizeManifestStoreRequest request, AsyncContext context,
      absl::AnyInvocable<void(absl::StatusOr<FinalizeManifestStoreResponse>) &&>
          cb) const = 0;
  // Blocking version.
  absl::StatusOr<FinalizeManifestStoreResponse> FinalizeManifestStore(
      FinalizeManifestStoreRequest request) const;
};
}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_GENERATOR_GENERATOR_H_
