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

#include "jumbf/internal/serialization_utils.h"

#include <climits>
#include <cstddef>
#include <cstdint>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "riegeli/base/byte_fill.h"
#include "riegeli/bytes/backward_writer.h"
#include "riegeli/endian/endian_writing.h"

#define WRITER_CALL_OR_RETURN(writer, call) \
  do {                                      \
    if (!writer->call) {                    \
      return writer->status();              \
    }                                       \
  } while (false)

namespace jumbf_internal {

// This library stores non-text data in strings and string_views, and reads
// values from byte offsets within them. No effort has been made to take into
// account alternate char widths.
static_assert(CHAR_BIT == 8);

absl::StatusOr<absl::string_view> ConsumeNullTerminated(absl::string_view* sv) {
  size_t len = sv->find('\0');
  if (len == absl::string_view::npos) {
    return absl::OutOfRangeError(
        "ran out of input bytes before reading null terminator");
  }

  // `len` does not include null terminator, which would have been contained
  // within the bounds of `sv`.
  absl::string_view output = sv->substr(0, len);
  sv->remove_prefix(len + 1);
  return output;
}

// Consumes the first `n` bytes of `sv`.
absl::StatusOr<absl::string_view> ConsumeBytes(absl::string_view* sv,
                                               size_t n) {
  if (sv->length() < n) {
    return absl::OutOfRangeError(absl::StrCat("ran out of input bytes; ", n,
                                              " bytes requested, ",
                                              sv->length(), " remaining"));
  }

  absl::string_view output = sv->substr(0, n);
  sv->remove_prefix(n);
  return output;
}

absl::Status WriteRaw(absl::Cord content, riegeli::BackwardWriter* writer) {
  WRITER_CALL_OR_RETURN(writer, Write(std::move(content)));
  return absl::OkStatus();
}

absl::Status WriteNulTerminated(absl::Cord content,
                                riegeli::BackwardWriter* writer) {
  for (absl::string_view chunk : content.Chunks()) {
    if (absl::StrContains(chunk, '\0')) {
      return absl::InvalidArgumentError(
          "cannot create NUL-terminated string from content: content contains "
          "NUL");
    }
  }
  WRITER_CALL_OR_RETURN(writer, WriteByte('\0'));
  WRITER_CALL_OR_RETURN(writer, Write(std::move(content)));
  return absl::OkStatus();
}

template <>
absl::Status WriteInteger(uint8_t n, riegeli::BackwardWriter* writer) {
  WRITER_CALL_OR_RETURN(writer, WriteByte(n));
  return absl::OkStatus();
}
template <>
absl::Status WriteInteger(uint32_t n, riegeli::BackwardWriter* writer) {
  char buf[4];
  riegeli::WriteBigEndian<uint32_t>(n, buf);
  WRITER_CALL_OR_RETURN(writer, Write(absl::string_view(buf, 4)));
  return absl::OkStatus();
}
template <>
absl::Status WriteInteger(uint64_t n, riegeli::BackwardWriter* writer) {
  char buf[8];
  riegeli::WriteBigEndian<uint64_t>(n, buf);
  WRITER_CALL_OR_RETURN(writer, Write(absl::string_view(buf, 8)));
  return absl::OkStatus();
}

absl::Status WritePadding(uint64_t length, riegeli::BackwardWriter* writer) {
  WRITER_CALL_OR_RETURN(writer, Write(riegeli::ByteFill(length)));
  return absl::OkStatus();
}

}  // namespace jumbf_internal
