// 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.
//

// SuperBoxEncoder: Stateful JUMBF encoder.
//
// This class tracks box lengths to correctly write headers. See
// c2pa/jumbf/box_builder_test.cc for usage
// examples.

#ifndef THIRD_PARTY_CREDENTIO_JUMBF_BOX_BUILDER_H_
#define THIRD_PARTY_CREDENTIO_JUMBF_BOX_BUILDER_H_

#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>
#include <utility>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "jumbf/encode_params.h"
#include "riegeli/bytes/cord_backward_writer.h"
#include "uuid/uuid.h"

namespace jumbf {

enum class SuperBoxBuildingState {
  kEmpty,
  kContainsPadding,
  kContainsContent,
};

class BuiltSuperBox;

class SuperBoxBuilder {
 public:
  SuperBoxBuilder(credentio::Uuid type_uuid,
                  DescriptionBoxOptions description_options);

  // Adds a padding box to the superbox. May only be called on an empty encoder.
  absl::Status AddPadding(size_t len);

  // Adds a child superbox as a content box of this superbox. New boxes are
  // added to the front of this box's content.
  absl::Status AddChild(SuperBoxBuilder&& child);
  // Add a child superbox as a content box of this superbox. New boxes are
  // added to the front of this box's content.
  absl::Status AddChild(BuiltSuperBox&& serialized_superbox);
  // Add a child superbox as a content box of this superbox. New boxes are
  // added to the front of this box's content.
  absl::Status AddChild(absl::Cord serialized_superbox);
  // Adds a content box.  New boxes are added to the front of this box's
  // content.
  absl::Status AddContent(uint32_t tbox, absl::Cord payload);

  // Finish writing the box. This consumes the builder, use
  // `std::move(builder).Finalize()`;
  absl::StatusOr<BuiltSuperBox> Finalize() &&;

 private:
  absl::Status AssertStateIn(
      absl::Span<const SuperBoxBuildingState> want) const;

  void StateTransition(absl::Span<const SuperBoxBuildingState> from,
                       SuperBoxBuildingState to);

  credentio::Uuid type_uuid_;
  // Need to cache the underlying `absl::Cord` for the label, because the
  // `DescriptionBoxOptions` gets consumed by `Finalize()`.
  std::optional<absl::Cord> description_label_;
  DescriptionBoxOptions description_options_;
  SuperBoxBuildingState state_ = SuperBoxBuildingState::kEmpty;
  riegeli::CordBackwardWriter<absl::Cord> writer_;
};

class BuiltSuperBox {
 public:
  BuiltSuperBox() = default;

  std::optional<absl::string_view> description_label() const {
    return description_label_;
  }

  // Peeks at the underlying cord. Less efficient than `AsCord()` if the value
  // is to be stored elsewhere.
  const absl::Cord& Peek() const { return rep_; }
  // Moves the underlying cord out of this object. Use
  // `std::move(box).AsCord()`.
  absl::Cord AsCord() && {
    description_label_ = std::nullopt;
    return std::move(rep_);
  }

 private:
  friend absl::StatusOr<BuiltSuperBox> SuperBoxBuilder::Finalize() &&;

  explicit BuiltSuperBox(absl::Cord&& rep,
                         std::optional<std::string> description_label)
      : rep_(std::move(rep)),
        description_label_(std::move(description_label)) {}
  absl::Cord rep_;
  std::optional<std::string> description_label_;
};

template <typename Sink>
void AbslStringify(Sink& sink, SuperBoxBuildingState state) {
  switch (state) {
    case SuperBoxBuildingState::kEmpty:
      sink.Append("EMPTY");
      return;
    case jumbf::SuperBoxBuildingState::kContainsPadding:
      sink.Append("CONTAINS_PADDING");
      return;
    case jumbf::SuperBoxBuildingState::kContainsContent:
      sink.Append("CONTAINS_CONTENT");
      return;
  };
  LOG(DFATAL) << "Fell through end of exhaustive switch statement.";
  sink.Append(absl::StrCat("UNKNOWN_STATE_", static_cast<int>(state)));
}

}  // namespace jumbf

#endif  // THIRD_PARTY_CREDENTIO_JUMBF_BOX_BUILDER_H_
