// Copyright 2018 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 "net/third_party/quiche/src/quic/core/quic_connection_id.h"

#include <cstdint>
#include <cstring>
#include <iomanip>

#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"

namespace quic {

QuicConnectionId::QuicConnectionId() {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    id64_ = 0;
    length_ = sizeof(uint64_t);
    return;
  }
  length_ = 0;
}

QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
  QUIC_BUG_IF(!QuicConnectionIdUseNetworkByteOrder())
      << "new constructor called when flag disabled";
  if (length > kQuicMaxConnectionIdLength) {
    QUIC_BUG << "Attempted to create connection ID of length " << length;
    length = kQuicMaxConnectionIdLength;
  }
  length_ = length;
  if (length_ > 0) {
    memcpy(data_, data, length_);
  }
  QUIC_RESTART_FLAG_COUNT_N(quic_variable_length_connection_ids_server, 2, 3);
}

QuicConnectionId::QuicConnectionId(uint64_t connection_id64)
    : length_(sizeof(uint64_t)) {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    id64_ = connection_id64;
    return;
  }
  QUIC_BUG_IF(QuicConnectionIdSupportsVariableLength(Perspective::IS_CLIENT) &&
              QuicConnectionIdSupportsVariableLength(Perspective::IS_SERVER))
      << "old constructor called when flag enabled";
  const uint64_t connection_id64_net = QuicEndian::HostToNet64(connection_id64);
  memcpy(&data_, &connection_id64_net, sizeof(connection_id64_net));
}

QuicConnectionId::~QuicConnectionId() {}

uint64_t QuicConnectionId::ToUInt64() const {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return id64_;
  }
  QUIC_BUG_IF(QuicConnectionIdSupportsVariableLength(Perspective::IS_CLIENT) &&
              QuicConnectionIdSupportsVariableLength(Perspective::IS_SERVER))
      << "ToUInt64 called when flag enabled";
  uint64_t connection_id64_net = 0;
  memcpy(&connection_id64_net, &data_,
         std::min<size_t>(static_cast<size_t>(length_),
                          sizeof(connection_id64_net)));
  return QuicEndian::NetToHost64(connection_id64_net);
}

const char* QuicConnectionId::data() const {
  QUIC_BUG_IF(!QuicConnectionIdUseNetworkByteOrder())
      << "data called when flag disabled";
  QUIC_RESTART_FLAG_COUNT_N(quic_variable_length_connection_ids_server, 3, 3);
  return data_;
}

char* QuicConnectionId::mutable_data() {
  QUIC_BUG_IF(!QuicConnectionIdUseNetworkByteOrder())
      << "mutable_data called when flag disabled";
  return data_;
}

uint8_t QuicConnectionId::length() const {
  return length_;
}

void QuicConnectionId::set_length(uint8_t length) {
  QUIC_BUG_IF(!QuicConnectionIdUseNetworkByteOrder())
      << "set_length called when flag disabled";
  length_ = length;
}

bool QuicConnectionId::IsEmpty() const {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return id64_ == 0;
  }
  return length_ == 0;
}

size_t QuicConnectionId::Hash() const {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return id64_;
  }
  uint64_t data_bytes[3] = {0, 0, 0};
  static_assert(sizeof(data_bytes) >= sizeof(data_), "sizeof(data_) changed");
  memcpy(data_bytes, data_, length_);
  // This Hash function is designed to return the same value
  // as ToUInt64() when the connection ID length is 64 bits.
  return QuicEndian::NetToHost64(kQuicDefaultConnectionIdLength ^ length_ ^
                                 data_bytes[0] ^ data_bytes[1] ^ data_bytes[2]);
}

QuicString QuicConnectionId::ToString() const {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return QuicTextUtils::Uint64ToString(id64_);
  }
  if (IsEmpty()) {
    return QuicString("0");
  }
  return QuicTextUtils::HexEncode(data_, length_);
}

std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) {
  os << v.ToString();
  return os;
}

bool QuicConnectionId::operator==(const QuicConnectionId& v) const {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return id64_ == v.id64_;
  }
  return length_ == v.length_ && memcmp(data_, v.data_, length_) == 0;
}

bool QuicConnectionId::operator!=(const QuicConnectionId& v) const {
  return !(v == *this);
}

bool QuicConnectionId::operator<(const QuicConnectionId& v) const {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return id64_ < v.id64_;
  }
  if (length_ < v.length_) {
    return true;
  }
  if (length_ > v.length_) {
    return false;
  }
  return memcmp(data_, v.data_, length_) < 0;
}

QuicConnectionId EmptyQuicConnectionId() {
  return QuicConnectionId();
}

QuicConnectionId QuicConnectionIdFromUInt64(uint64_t connection_id64) {
  return QuicConnectionId(connection_id64);
}

uint64_t QuicConnectionIdToUInt64(QuicConnectionId connection_id) {
  return connection_id.ToUInt64();
}

bool QuicConnectionIdUseNetworkByteOrder() {
  const bool res = GetQuicRestartFlag(quic_connection_ids_network_byte_order);
  if (res) {
    QUIC_RESTART_FLAG_COUNT(quic_connection_ids_network_byte_order);
  }
  return res;
}

bool QuicConnectionIdSupportsVariableLength(Perspective perspective) {
  if (!QuicConnectionIdUseNetworkByteOrder()) {
    return false;
  }
  bool res;
  if (perspective == Perspective::IS_SERVER) {
    res = GetQuicRestartFlag(quic_variable_length_connection_ids_server);
    if (res) {
      QUIC_RESTART_FLAG_COUNT_N(quic_variable_length_connection_ids_server, 1,
                                3);
    }
  } else {
    res = GetQuicRestartFlag(quic_variable_length_connection_ids_client);
    if (res) {
      QUIC_RESTART_FLAG_COUNT(quic_variable_length_connection_ids_client);
    }
  }
  return res;
}

static_assert(kQuicDefaultConnectionIdLength == sizeof(uint64_t),
              "kQuicDefaultConnectionIdLength changed");
static_assert(kQuicDefaultConnectionIdLength == PACKET_8BYTE_CONNECTION_ID,
              "kQuicDefaultConnectionIdLength changed");

}  // namespace quic
