// 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_FORMATS_BMFF_WRITER_H_
#define THIRD_PARTY_CREDENTIO_FORMATS_BMFF_WRITER_H_

#include <memory>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "async/async_context.h"
#include "generator/generator.h"
#include "proto/generator.pb.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/writer.h"
#include "utils/byte_instruction.h"

namespace credentio {

// Writer of C2PA manifest stores into BMFF assets.
class BmffWriter {
 public:
  // Information about the C2PA manifest store embedded in the output asset.
  struct OutputMetadata {
    // Whether the C2PA active manifest embedded in the output asset has a
    // timestamp.
    bool timestamp_included = false;
  };

  using ExclusionProcessor = absl::AnyInvocable<absl::Status(
      riegeli::Reader&, GenerateManifestStoreRequest&) const>;

  struct Options {
    ExclusionProcessor exclusion_processor = nullptr;
  };

  // Creates a BMFF writer.
  //
  // The generator must outlive the writer.
  explicit BmffWriter(const ManifestStoreGenerator* absl_nonnull generator)
      : BmffWriter(generator, Options{}) {}

  BmffWriter(const ManifestStoreGenerator* absl_nonnull generator,
             Options options)
      : generator_(*ABSL_DIE_IF_NULL(generator)),
        options_(std::move(options)) {}

  // Generates a C2PA manifest store and embeds it into a copy of the given
  // asset. The riegeli::Reader and riegeli::Writer cannot be pointed to the
  // same underlying data.
  void Write(GenerateManifestStoreRequest request,
             riegeli::Reader* absl_nonnull source,
             riegeli::Writer* absl_nonnull destination,
             OutputMetadata* absl_nullable output_metadata,
             AsyncContext context,
             absl::AnyInvocable<void(absl::Status) &&> cb) const;
  // Blocking version.
  absl::Status Write(
      GenerateManifestStoreRequest request,
      riegeli::Reader* absl_nonnull source,
      riegeli::Writer* absl_nonnull destination,
      OutputMetadata* absl_nullable output_metadata = nullptr) const;

  // Generates a C2PA manifest store and embeds it in the given asset just
  // as the above methods, but does so in-place.
  //
  // The supplied writer must support random access and read mode. Read mode is
  // not enabled by default on the riegeli::StringWriter or riegeli::FileWriter,
  // it can be enabled by passing an Option to their constructors:
  //  - StringWriter(&data, StringWriterBase::Options().set_append(true));
  //  - FileWriter(filepath, FileWriterBase::Options().set_existing(true));
  void Write(GenerateManifestStoreRequest request,
             riegeli::Writer* absl_nonnull asset,
             OutputMetadata* absl_nullable output_metadata,
             AsyncContext context,
             absl::AnyInvocable<void(absl::Status) &&> cb) const;
  // Blocking version.
  absl::Status Write(
      GenerateManifestStoreRequest request, riegeli::Writer* absl_nonnull asset,
      OutputMetadata* absl_nullable output_metadata = nullptr) const;

 private:
  void WriteInternal(
      GenerateManifestStoreRequest request,
      riegeli::Reader* absl_nonnull source,
      OutputMetadata* absl_nullable output_metadata,
      std::shared_ptr<std::vector<ByteInstruction>> byte_instructions,
      AsyncContext context, absl::AnyInvocable<void(absl::Status) &&> cb) const;

  const ManifestStoreGenerator& generator_;
  Options options_;
};

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_FORMATS_BMFF_WRITER_H_
