// Copyright 2018 The Chromium OS 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 "patchpanel/subnet.h"

#include <arpa/inet.h>

#include <string>
#include <utility>

#include <base/bind.h>
#include <base/logging.h>

#include "patchpanel/net_util.h"

namespace {
// Returns the offset from the base address given in network-byte order for
// the address given in network-byte order, or 0 if the second address is
// lower than the base address. Returns the offset in host-byte order.
uint32_t OffsetFromBaseAddress(uint32_t base_no, uint32_t addr_no) {
  if (ntohl(addr_no) < ntohl(base_no))
    return 0;
  return ntohl(addr_no) - ntohl(base_no);
}
// Adds a positive offset given in host order to the address given in
// network byte order. Returns the address in network-byte order.
uint32_t AddOffset(uint32_t addr_no, uint32_t offset_ho) {
  return htonl(ntohl(addr_no) + offset_ho);
}
}  // namespace

namespace patchpanel {

SubnetAddress::SubnetAddress(uint32_t addr,
                             uint32_t prefix_length,
                             base::Closure release_cb)
    : addr_(addr),
      prefix_length_(prefix_length),
      release_cb_(std::move(release_cb)) {}

SubnetAddress::~SubnetAddress() {
  release_cb_.Run();
}

uint32_t SubnetAddress::Address() const {
  return addr_;
}

std::string SubnetAddress::ToCidrString() const {
  return IPv4AddressToCidrString(addr_, prefix_length_);
}

std::string SubnetAddress::ToIPv4String() const {
  return IPv4AddressToString(addr_);
}

uint32_t SubnetAddress::Netmask() const {
  return Ipv4Netmask(prefix_length_);
}

Subnet::Subnet(uint32_t base_addr,
               uint32_t prefix_length,
               base::Closure release_cb)
    : base_addr_(base_addr),
      prefix_length_(prefix_length),
      release_cb_(std::move(release_cb)),
      weak_factory_(this) {
  CHECK_LT(prefix_length, 32);

  addrs_.resize(1ull << (32 - prefix_length), false);

  // Mark the base address and broadcast address as allocated.
  addrs_.front() = true;
  addrs_.back() = true;
}

Subnet::~Subnet() {
  release_cb_.Run();
}

std::unique_ptr<SubnetAddress> Subnet::Allocate(uint32_t addr) {
  return AllocateAtOffset(OffsetFromBaseAddress(base_addr_, addr) - 1);
}

std::unique_ptr<SubnetAddress> Subnet::AllocateAtOffset(uint32_t offset) {
  uint32_t addr = AddressAtOffset(offset);
  if (addr == INADDR_ANY) {
    return nullptr;
  }

  if (addrs_[offset + 1]) {
    // Address is already allocated.
    return nullptr;
  }

  addrs_[offset + 1] = true;
  return std::make_unique<SubnetAddress>(
      addr, prefix_length_,
      base::Bind(&Subnet::Free, weak_factory_.GetWeakPtr(), offset + 1));
}

uint32_t Subnet::AddressAtOffset(uint32_t offset) const {
  if (offset < 0 || offset >= AvailableCount())
    return INADDR_ANY;

  // The first usable IP is after the base address.
  return AddOffset(base_addr_, 1 + offset);
}

uint32_t Subnet::AvailableCount() const {
  // The available IP count is all IPs in a subnet, minus the network ID
  // and the broadcast address.
  return addrs_.size() - 2;
}

uint32_t Subnet::BaseAddress() const {
  return base_addr_;
}

uint32_t Subnet::Netmask() const {
  return Ipv4Netmask(prefix_length_);
}

uint32_t Subnet::Prefix() const {
  return base_addr_ & Netmask();
}

uint32_t Subnet::PrefixLength() const {
  return prefix_length_;
}

std::string Subnet::ToCidrString() const {
  return IPv4AddressToCidrString(base_addr_, prefix_length_);
}

void Subnet::Free(uint32_t offset) {
  DCHECK_NE(offset, 0);
  DCHECK_LT(offset, addrs_.size() - 1);

  addrs_[offset] = false;
}

}  // namespace patchpanel
