// 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_TEST_UTILS_H_
#define THIRD_PARTY_CREDENTIO_FORMATS_BMFF_TEST_UTILS_H_

#include <cstdint>
#include <string>

#include "absl/log/check.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "testing/test_string_utils.h"

namespace credentio_testing {

using ::credentio::kC2paBmffBoxUuid;

inline constexpr absl::string_view kNul("\x00", 1);

inline std::string Box(absl::string_view type, absl::string_view data) {
  CHECK_EQ(type.size(), 4);
  return absl::StrCat(Uint32Str(data.size() + 8), type, data);
}

inline std::string BadBox(absl::string_view type, absl::string_view data,
                          uint32_t data_size) {
  CHECK_EQ(type.size(), 4);
  return absl::StrCat(Uint32Str(data_size), type, data);
}

inline std::string BigBox(absl::string_view type, absl::string_view data) {
  CHECK_EQ(type.size(), 4);
  return absl::StrCat(Uint32Str(1), type, Uint64Str(data.size() + 16), data);
}

inline std::string BoxVersion(uint8_t version) { return Uint8Str(version); }

inline std::string BoxFlags(uint32_t flags) {
  CHECK_EQ(flags & 0xff000000, 0);
  return Uint32Str(flags).substr(1);
}

// Returns the data payload of a UUID box, suitable for passing to Box() or
// BigBox().
inline std::string UuidBoxPayload(absl::string_view uuid,
                                  absl::string_view version,
                                  absl::string_view flags,
                                  absl::string_view data) {
  CHECK_EQ(uuid.size(), 16);
  CHECK_EQ(version.size(), 1);
  CHECK_EQ(flags.size(), 3);
  return absl::StrCat(uuid, version, flags, data);
}

// Returns the data payload of a C2PA manifest box, suitable for passing to
// Box() or BigBox().
inline std::string C2paBoxPayload(absl::string_view purpose,
                                  absl::string_view data) {
  return UuidBoxPayload(kC2paBmffBoxUuid, BoxVersion(0), BoxFlags(0),
                        absl::StrCat(purpose, kNul, data));
}

// Returns the data payload of a well-formed C2PA manifest box (i.e., starting
// with an absolute offset to the first `merkle` C2PA box), suitable for passing
// to Box() or BigBox().
inline std::string ManifestBoxPayload(uint64_t merkle_offset,
                                      absl::string_view data) {
  return C2paBoxPayload("manifest",
                        absl::StrCat(Uint64Str(merkle_offset), data));
}

// Returns a full C2PA manifest box encoded as a standard (small) Box.
inline std::string ManifestBox(uint64_t merkle_offset, absl::string_view data) {
  return Box("uuid", ManifestBoxPayload(merkle_offset, data));
}

// Returns a full C2PA manifest box encoded as a BigBox.
inline std::string ManifestBigBox(uint64_t merkle_offset,
                                  absl::string_view data) {
  return BigBox("uuid", ManifestBoxPayload(merkle_offset, data));
}

inline std::string C2paUuidBox(absl::string_view data,
                               absl::string_view box_purpose = "manifest",
                               uint64_t merkle_offset = 0) {
  return Box("uuid",
             C2paBoxPayload(box_purpose,
                            absl::StrCat(Uint64Str(merkle_offset), data)));
}

}  // namespace credentio_testing

#endif  // THIRD_PARTY_CREDENTIO_FORMATS_BMFF_TEST_UTILS_H_
