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

#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_text_utils.h"

namespace quic {

QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {}

QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
  static_assert(
      kQuicMaxConnectionIdLength <= std::numeric_limits<uint8_t>::max(),
      "kQuicMaxConnectionIdLength too high");
  if (length > kQuicMaxConnectionIdLength) {
    QUIC_BUG << "Attempted to create connection ID of length " << length;
    length = kQuicMaxConnectionIdLength;
  }
  length_ = length;
  if (length_ == 0) {
    return;
  }
  if (!GetQuicRestartFlag(quic_use_allocated_connection_ids)) {
    memcpy(data_, data, length_);
    return;
  }
  QUIC_RESTART_FLAG_COUNT_N(quic_use_allocated_connection_ids, 1, 6);
  if (length_ <= sizeof(data_short_)) {
    memcpy(data_short_, data, length_);
    return;
  }
  data_long_ = reinterpret_cast<char*>(malloc(length_));
  CHECK_NE(nullptr, data_long_);
  memcpy(data_long_, data, length_);
}

QuicConnectionId::~QuicConnectionId() {
  if (!GetQuicRestartFlag(quic_use_allocated_connection_ids)) {
    return;
  }
  QUIC_RESTART_FLAG_COUNT_N(quic_use_allocated_connection_ids, 2, 6);
  if (length_ > sizeof(data_short_)) {
    free(data_long_);
    data_long_ = nullptr;
  }
}

QuicConnectionId::QuicConnectionId(const QuicConnectionId& other)
    : QuicConnectionId(other.data(), other.length()) {}

QuicConnectionId& QuicConnectionId::operator=(const QuicConnectionId& other) {
  set_length(other.length());
  memcpy(mutable_data(), other.data(), length_);
  return *this;
}

const char* QuicConnectionId::data() const {
  if (!GetQuicRestartFlag(quic_use_allocated_connection_ids)) {
    return data_;
  }
  QUIC_RESTART_FLAG_COUNT_N(quic_use_allocated_connection_ids, 3, 6);
  if (length_ <= sizeof(data_short_)) {
    return data_short_;
  }
  return data_long_;
}

char* QuicConnectionId::mutable_data() {
  if (!GetQuicRestartFlag(quic_use_allocated_connection_ids)) {
    return data_;
  }
  QUIC_RESTART_FLAG_COUNT_N(quic_use_allocated_connection_ids, 4, 6);
  if (length_ <= sizeof(data_short_)) {
    return data_short_;
  }
  return data_long_;
}

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

void QuicConnectionId::set_length(uint8_t length) {
  if (GetQuicRestartFlag(quic_use_allocated_connection_ids)) {
    QUIC_RESTART_FLAG_COUNT_N(quic_use_allocated_connection_ids, 5, 6);
    char temporary_data[sizeof(data_short_)];
    if (length > sizeof(data_short_)) {
      if (length_ <= sizeof(data_short_)) {
        // Copy data from data_short_ to data_long_.
        memcpy(temporary_data, data_short_, length_);
        data_long_ = reinterpret_cast<char*>(malloc(length));
        CHECK_NE(nullptr, data_long_);
        memcpy(data_long_, temporary_data, length_);
      } else {
        // Resize data_long_.
        char* realloc_result =
            reinterpret_cast<char*>(realloc(data_long_, length));
        CHECK_NE(nullptr, realloc_result);
        data_long_ = realloc_result;
      }
    } else if (length_ > sizeof(data_short_)) {
      // Copy data from data_long_ to data_short_.
      memcpy(temporary_data, data_long_, length);
      free(data_long_);
      data_long_ = nullptr;
      memcpy(data_short_, temporary_data, length);
    }
  }
  length_ = length;
}

bool QuicConnectionId::IsEmpty() const {
  return length_ == 0;
}

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

std::string QuicConnectionId::ToString() const {
  if (IsEmpty()) {
    return std::string("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 {
  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 (length_ < v.length_) {
    return true;
  }
  if (length_ > v.length_) {
    return false;
  }
  return memcmp(data(), v.data(), length_) < 0;
}

QuicConnectionId EmptyQuicConnectionId() {
  return QuicConnectionId();
}

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

}  // namespace quic
