// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GARNET_LIB_INET_IP_ADDRESS_H_
#define GARNET_LIB_INET_IP_ADDRESS_H_

#include <arpa/inet.h>

#include "lib/fxl/logging.h"

#include <fuchsia/net/cpp/fidl.h>

namespace inet {

// Represents a V4 or V6 IP address.
class IpAddress {
 public:
  static const IpAddress kInvalid;
  static const IpAddress kV4Loopback;
  static const IpAddress kV6Loopback;

  // Creates an IpAddress from a string containing a numeric IP address. Returns
  // |kInvalid| if |address_string| cannot be converted into a valid IP address.
  static IpAddress FromString(const std::string address_string,
                              sa_family_t family = AF_UNSPEC);

  // Creates an invalid IP address.
  IpAddress();

  // Creates an IPV4 address from four address bytes.
  IpAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3);

  // Creates an IPV4 address from an in_addr_t.
  explicit IpAddress(in_addr_t addr);

  // Creates an IPV4 address from an in_addr struct.
  explicit IpAddress(const in_addr& addr);

  // Creates an IPV6 address from eight address words.
  IpAddress(uint16_t w0, uint16_t w1, uint16_t w2, uint16_t w3, uint16_t w4,
            uint16_t w5, uint16_t w6, uint16_t w7);

  // Creates an IPV6 address from two address words (first and last).
  IpAddress(uint16_t w0, uint16_t w7);

  // Creates an IPV6 address from an in6_addr struct.
  explicit IpAddress(const in6_addr& addr);

  // Creates an address from a sockaddr struct.
  explicit IpAddress(const sockaddr* addr);

  // Creates an address from a sockaddr_storage struct.
  explicit IpAddress(const sockaddr_storage& addr);

  // Creates an address from an IpAddress struct.
  explicit IpAddress(const fuchsia::net::IpAddress* addr);

  bool is_valid() const { return family_ != AF_UNSPEC; }

  sa_family_t family() const { return family_; }

  bool is_v4() const { return family() == AF_INET; }

  bool is_v6() const { return family() == AF_INET6; }

  bool is_loopback() const;

  const in_addr& as_in_addr() const {
    FXL_DCHECK(is_v4());
    return v4_;
  }

  in_addr_t as_in_addr_t() const {
    FXL_DCHECK(is_v4());
    return v4_.s_addr;
  }

  const in6_addr& as_in6_addr() const {
    FXL_DCHECK(is_v6());
    return v6_;
  }

  const uint8_t* as_bytes() const { return v6_.s6_addr; }

  const uint16_t* as_words() const { return v6_.s6_addr16; }

  size_t byte_count() const {
    return is_v4() ? sizeof(in_addr) : sizeof(in6_addr);
  }

  size_t word_count() const { return byte_count() / sizeof(uint16_t); }

  std::string ToString() const;

  explicit operator bool() const { return is_valid(); }

  bool operator==(const IpAddress& other) const {
    return is_v4() == other.is_v4() &&
           std::memcmp(as_bytes(), other.as_bytes(), byte_count()) == 0;
  }

  bool operator!=(const IpAddress& other) const { return !(*this == other); }

 private:
  sa_family_t family_;
  union {
    in_addr v4_;
    in6_addr v6_;
  };
};

std::ostream& operator<<(std::ostream& os, const IpAddress& value);

}  // namespace inet

template <>
struct std::hash<inet::IpAddress> {
  std::size_t operator()(const inet::IpAddress& address) const noexcept {
    size_t hash = 0;

    auto byte_ptr = address.as_bytes();
    for (size_t i = 0; i < address.byte_count(); ++i) {
      hash = (hash << 1) ^ *byte_ptr;
      ++byte_ptr;
    }

    return hash;
  }
};

#endif  // GARNET_LIB_INET_IP_ADDRESS_H_
