// Copyright (c) 2019 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/qbone/platform/ip_range.h"

#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h"

namespace quic {

namespace {

constexpr size_t kIPv4Size = 32;
constexpr size_t kIPv6Size = 128;

QuicIpAddress TruncateToLength(const QuicIpAddress& input,
                               size_t* prefix_length) {
  QuicIpAddress output;
  if (input.IsIPv4()) {
    if (*prefix_length > kIPv4Size) {
      *prefix_length = kIPv4Size;
      return input;
    }
    uint32_t raw_address =
        *reinterpret_cast<const uint32_t*>(input.ToPackedString().data());
    raw_address = QuicEndian::NetToHost32(raw_address);
    raw_address &= ~0U << (kIPv4Size - *prefix_length);
    raw_address = QuicEndian::HostToNet32(raw_address);
    output.FromPackedString(reinterpret_cast<const char*>(&raw_address),
                            sizeof(raw_address));
    return output;
  }
  if (input.IsIPv6()) {
    if (*prefix_length > kIPv6Size) {
      *prefix_length = kIPv6Size;
      return input;
    }
    uint64_t raw_address[2];
    memcpy(raw_address, input.ToPackedString().data(), sizeof(raw_address));
    // raw_address[0] holds higher 8 bytes in big endian and raw_address[1]
    // holds lower 8 bytes. Converting each to little endian for us to mask bits
    // out.
    // The endianess between raw_address[0] and raw_address[1] is handled
    // explicitly by handling lower and higher bytes separately.
    raw_address[0] = QuicEndian::NetToHost64(raw_address[0]);
    raw_address[1] = QuicEndian::NetToHost64(raw_address[1]);
    if (*prefix_length <= kIPv6Size / 2) {
      raw_address[0] &= ~uint64_t{0} << (kIPv6Size / 2 - *prefix_length);
      raw_address[1] = 0;
    } else {
      raw_address[1] &= ~uint64_t{0} << (kIPv6Size - *prefix_length);
    }
    raw_address[0] = QuicEndian::HostToNet64(raw_address[0]);
    raw_address[1] = QuicEndian::HostToNet64(raw_address[1]);
    output.FromPackedString(reinterpret_cast<const char*>(raw_address),
                            sizeof(raw_address));
    return output;
  }
  return output;
}

}  // namespace

IpRange::IpRange(const QuicIpAddress& prefix, size_t prefix_length)
    : prefix_(prefix), prefix_length_(prefix_length) {
  prefix_ = TruncateToLength(prefix_, &prefix_length_);
}

bool IpRange::operator==(IpRange other) const {
  return prefix_ == other.prefix_ && prefix_length_ == other.prefix_length_;
}

bool IpRange::operator!=(IpRange other) const {
  return !(*this == other);
}

bool IpRange::FromString(const string& range) {
  size_t slash_pos = range.find('/');
  if (slash_pos == string::npos) {
    return false;
  }
  QuicIpAddress prefix;
  bool success = prefix.FromString(range.substr(0, slash_pos));
  if (!success) {
    return false;
  }
  uint64_t num_processed = 0;
  size_t prefix_length = std::stoi(range.substr(slash_pos + 1), &num_processed);
  if (num_processed + 1 + slash_pos != range.length()) {
    return false;
  }
  prefix_ = TruncateToLength(prefix, &prefix_length);
  prefix_length_ = prefix_length;
  return true;
}

QuicIpAddress IpRange::FirstAddressInRange() {
  return prefix();
}

}  // namespace quic
