// Copyright (c) 2022 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/quic/core/deterministic_connection_id_generator.h"

#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_logging.h"

namespace quic {

DeterministicConnectionIdGenerator::DeterministicConnectionIdGenerator(
    uint8_t expected_connection_id_length)
    : expected_connection_id_length_(expected_connection_id_length) {
  if (expected_connection_id_length_ >
      kQuicMaxConnectionIdWithLengthPrefixLength) {
    QUIC_BUG(quic_bug_465151159_01)
        << "Issuing connection IDs longer than allowed in RFC9000";
  }
}

std::optional<QuicConnectionId>
DeterministicConnectionIdGenerator::GenerateNextConnectionId(
    const QuicConnectionId& original) {
  if (expected_connection_id_length_ == 0) {
    return EmptyQuicConnectionId();
  }
  const uint64_t connection_id_hash64 = QuicUtils::FNV1a_64_Hash(
      absl::string_view(original.data(), original.length()));
  if (expected_connection_id_length_ <= sizeof(uint64_t)) {
    return QuicConnectionId(
        reinterpret_cast<const char*>(&connection_id_hash64),
        expected_connection_id_length_);
  }
  char new_connection_id_data[255] = {};
  const absl::uint128 connection_id_hash128 = QuicUtils::FNV1a_128_Hash(
      absl::string_view(original.data(), original.length()));
  static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <=
                    sizeof(new_connection_id_data),
                "bad size");
  memcpy(new_connection_id_data, &connection_id_hash64,
         sizeof(connection_id_hash64));
  // TODO(martinduke): We don't have any test coverage of the line below. In
  // particular, if the memcpy somehow misses a byte, a test could check if one
  // byte position in generated connection IDs is always the same.
  memcpy(new_connection_id_data + sizeof(connection_id_hash64),
         &connection_id_hash128, sizeof(connection_id_hash128));
  return QuicConnectionId(new_connection_id_data,
                          expected_connection_id_length_);
}

std::optional<QuicConnectionId>
DeterministicConnectionIdGenerator::MaybeReplaceConnectionId(
    const QuicConnectionId& original, const ParsedQuicVersion& version) {
  if (original.length() == expected_connection_id_length_) {
    return std::optional<QuicConnectionId>();
  }
  QUICHE_DCHECK(version.AllowsVariableLengthConnectionIds());
  std::optional<QuicConnectionId> new_connection_id =
      GenerateNextConnectionId(original);
  // Verify that ReplaceShortServerConnectionId is deterministic.
  if (!new_connection_id.has_value()) {
    QUIC_BUG(unset_next_connection_id);
    return std::nullopt;
  }
  QUICHE_DCHECK_EQ(
      *new_connection_id,
      static_cast<QuicConnectionId>(*GenerateNextConnectionId(original)));
  QUICHE_DCHECK_EQ(expected_connection_id_length_, new_connection_id->length());
  QUIC_DLOG(INFO) << "Replacing incoming connection ID " << original << " with "
                  << *new_connection_id;
  return new_connection_id;
}

}  // namespace quic
