// 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 SRC_LIB_INET_SOCKET_ADDRESS_H_
#define SRC_LIB_INET_SOCKET_ADDRESS_H_

#include <arpa/inet.h>
#include <fuchsia/net/cpp/fidl.h>
#include <fuchsia/netstack/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <sys/socket.h>

#include <ostream>

#include "src/lib/inet/ip_address.h"
#include "src/lib/inet/ip_port.h"

namespace inet {

// Represents a V4 or V6 socket address.
class SocketAddress {
 public:
  static const SocketAddress kInvalid;

  // Creates an invalid socket.
  SocketAddress();

  // Creates an IPV4 socket address from four address bytes and an IpPort.
  SocketAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, IpPort port);

  // Creates an IPV4 socket address from an in_addr_t and an IpPort.
  SocketAddress(in_addr_t addr, IpPort port);

  // Creates an IPV4 socket address from an sockaddr_in struct.
  explicit SocketAddress(const sockaddr_in& addr);

  // Creates an IPV6 socket address from eight address words and an IpPort.
  SocketAddress(uint16_t w0, uint16_t w1, uint16_t w2, uint16_t w3, uint16_t w4, uint16_t w5,
                uint16_t w6, uint16_t w7, IpPort port);

  // Creates an IPV6 socket address from two address words and an IpPort.
  SocketAddress(uint16_t w0, uint16_t w7, IpPort port);

  // Creates an IPV6 socket address from an in6_addr struct and an IpPort.
  SocketAddress(const in6_addr& addr, IpPort port);

  // Creates an IPV6 socket address from an sockaddr_in6 struct.
  explicit SocketAddress(const sockaddr_in6& addr);

  // Creates a socket address from a IpAddress and an IpPort.
  SocketAddress(const IpAddress& addr, IpPort port, uint32_t scope_id = 0);

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

  // Creates a socket address from a fuchsia.netstack SocketAddress struct.
  explicit SocketAddress(const fuchsia::netstack::SocketAddress* addr);

  // Creates a socket address from a fuchsia.net SocketAddress struct.
  explicit SocketAddress(const fuchsia::net::SocketAddress* addr);

  // Creates a socket address from a fuchsia.net Ipv4SocketAddress struct.
  explicit SocketAddress(const fuchsia::net::Ipv4SocketAddress* addr);

  // Creates a socket address from a fuchsia.net Ipv6SocketAddress struct.
  explicit SocketAddress(const fuchsia::net::Ipv6SocketAddress* addr);

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

  sa_family_t family() const { return v4_.sin_family; }

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

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

  IpAddress address() const { return is_v4() ? IpAddress(v4_.sin_addr) : IpAddress(v6_.sin6_addr); }

  IpPort port() const { return IpPort::From_in_port_t(v4_.sin_port); }

  uint32_t scope_id() const { return as_sockaddr_in6().sin6_scope_id; }

  const sockaddr_in& as_sockaddr_in() const {
    FX_DCHECK(is_v4());
    return v4_;
  }

  const sockaddr_in6& as_sockaddr_in6() const {
    FX_DCHECK(is_v6());
    return v6_;
  }

  const sockaddr* as_sockaddr() const { return reinterpret_cast<const sockaddr*>(&v4_); }

  socklen_t socklen() const { return is_v4() ? sizeof(v4_) : sizeof(v6_); }

  std::string ToString() const;

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

  bool operator==(const SocketAddress& other) const {
    return is_v4() == other.is_v4() &&
           std::memcmp(as_sockaddr(), other.as_sockaddr(), socklen()) == 0;
  }

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

 private:
  void Build(const IpAddress& address, IpPort port, uint32_t scope_id);

  union {
    sockaddr_in v4_;
    sockaddr_in6 v6_;
  };
};

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

}  // namespace inet

template <>
struct std::hash<inet::SocketAddress> {
  std::size_t operator()(const inet::SocketAddress& address) const noexcept {
    return std::hash<inet::IpAddress>{}(address.address()) ^
           (std::hash<uint16_t>{}(address.port().as_uint16_t()) << 1);
  }
};

#endif  // SRC_LIB_INET_SOCKET_ADDRESS_H_
