// Copyright 2026 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/common/moq_varint.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <optional>

#include "absl/base/casts.h"
#include "absl/numeric/bits.h"
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_data_writer.h"
#include "quiche/common/quiche_endian.h"

namespace quiche {
namespace {

constexpr uint64_t kMaxEbmlVarintValue = (UINT64_C(1) << 56) - 2;

// The two varint dialects are similar, the notable differences are:
//   - MOQ varints use a sequence of 1s for encoding length, EBML uses 0s.
//   - EBML does not allow varints of length 9, meaning only 2^56 values are
//         encodable.
enum class VarintDialect { kMoq, kEbml };

template <VarintDialect dialect>
size_t GetVarintSizeForFirstByte(char first_byte_raw) {
  uint8_t first_byte = absl::bit_cast<uint8_t>(first_byte_raw);
  if constexpr (dialect == VarintDialect::kEbml) {
    first_byte = ~first_byte;
  }
  return absl::countl_one(first_byte) + 1;
}

template <VarintDialect dialect>
std::optional<uint64_t> ReadVarint(QuicheDataReader& reader) {
  if (reader.BytesRemaining() == 0) {
    return std::nullopt;
  }
  const size_t length = GetVarintSizeForFirstByte<dialect>(reader.PeekByte());
  if (reader.BytesRemaining() < length) {
    return std::nullopt;
  }
  if (dialect == VarintDialect::kEbml && length > 8) {
    return std::nullopt;
  }
  QUICHE_DCHECK_LE(length, 9u);

  absl::string_view data = reader.PeekRemainingPayload();
  uint64_t result = 0;
  if (length == 9) {
    memcpy(&result, data.data() + 1, 8);
  } else {
    char* result_start = reinterpret_cast<char*>(&result) + (8 - length);
    memcpy(result_start, data.data(), length);
    const uint8_t first_byte_mask = (1 << (8 - length)) - 1;
    *result_start &= first_byte_mask;
  }
  result = QuicheEndian::NetToHost64(result);
  reader.Seek(length);
  return result;
}

template <VarintDialect dialect>
size_t GetVarintLengthForValue(uint64_t value) {
  if (dialect == VarintDialect::kEbml) {
    // Avoid writing "all ones" sequences, as those have magic semantics in some
    // contexts (RFC 8794, Section 6.2).
    ++value;
  }
  // This is equivalent to `ceil(bit_width(value) / 7)`.
  size_t length = (6 + absl::bit_width(value)) / 7;
  return std::clamp<size_t>(length, 1, 9);
}

template <VarintDialect dialect>
[[nodiscard]] bool WriteVarint(QuicheDataWriter& writer, uint64_t value,
                               size_t length) {
  if (dialect == VarintDialect::kEbml && value > kMaxEbmlVarintValue) {
    return false;
  }
  QUICHE_DCHECK_GE(length, 1u);
  QUICHE_DCHECK_LE(length, 9u);

  if (length == 9) {
    QUICHE_DCHECK(dialect == VarintDialect::kMoq);
    return writer.WriteUInt8(0xff) && writer.WriteUInt64(value);
  }

  char buffer[8];
  value = QuicheEndian::HostToNet64(value);
  const char* input_start =
      reinterpret_cast<const char*>(&value) + (8 - length);
  memcpy(buffer, input_start, length);
  const uint8_t first_byte_data_mask = (1 << (8 - length)) - 1;
  const uint8_t first_byte_length_mask = ~first_byte_data_mask;
  uint8_t first_byte_length = 1 << (8 - length);
  if constexpr (dialect == VarintDialect::kMoq) {
    first_byte_length = ~first_byte_length;
  }
  buffer[0] = (buffer[0] & first_byte_data_mask) |
              (first_byte_length & first_byte_length_mask);
  return writer.WriteBytes(buffer, length);
}

}  // namespace

size_t GetMoqVarintLengthForFirstByte(char first_byte) {
  return GetVarintSizeForFirstByte<VarintDialect::kMoq>(first_byte);
}
size_t GetEbmlVarintLengthForFirstByte(char first_byte) {
  return GetVarintSizeForFirstByte<VarintDialect::kEbml>(first_byte);
}

size_t GetMoqVarintLengthForValue(uint64_t value) {
  return GetVarintLengthForValue<VarintDialect::kMoq>(value);
}
std::optional<size_t> GetEbmlVarintLengthForValue(uint64_t value) {
  if (value > kMaxEbmlVarintValue) {
    return std::nullopt;
  }
  return GetVarintLengthForValue<VarintDialect::kEbml>(value);
}

std::optional<uint64_t> ReadMoqVarint(QuicheDataReader& reader) {
  return ReadVarint<VarintDialect::kMoq>(reader);
}
std::optional<uint64_t> ReadEbmlVarint(QuicheDataReader& reader) {
  return ReadVarint<VarintDialect::kEbml>(reader);
}

[[nodiscard]] bool WriteMoqVarint(QuicheDataWriter& writer, uint64_t value) {
  const size_t length = GetVarintLengthForValue<VarintDialect::kMoq>(value);
  return WriteVarint<VarintDialect::kMoq>(writer, value, length);
}
[[nodiscard]] bool WriteEbmlVarint(QuicheDataWriter& writer, uint64_t value) {
  const size_t length = GetVarintLengthForValue<VarintDialect::kEbml>(value);
  return WriteVarint<VarintDialect::kEbml>(writer, value, length);
}
[[nodiscard]] bool WriteMoqVarintWithCustomLength(QuicheDataWriter& writer,
                                                  uint64_t value,
                                                  size_t length) {
  return WriteVarint<VarintDialect::kMoq>(writer, value, length);
}

}  // namespace quiche
