// Copyright 2019 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.

#pragma once

#include <netinet/in.h>
#ifndef __Fuchsia__
#include <sys/un.h>
#endif
#include <iosfwd>

#include "src/connectivity/overnet/lib/vocabulary/optional.h"

namespace overnet {

union IpAddr {
  sockaddr_in ipv4;
  sockaddr_in6 ipv6;
  sockaddr addr;
#ifndef __Fuchsia__
  sockaddr_un unix;
  static Optional<IpAddr> Unix(const std::string& name);
#endif

  Optional<IpAddr> WithPort(uint16_t port) const;

  static IpAddr AnyIpv4();
  static IpAddr AnyIpv6();

  const sockaddr* get() const { return &addr; }
  socklen_t length() const;

  Optional<IpAddr> AsIpv6() const;
  uint16_t port() const {
    switch (addr.sa_family) {
      case AF_INET:
        return htons(ipv4.sin_port);
      case AF_INET6:
        return htons(ipv6.sin6_port);
      default:
        return 0;
    }
  }

  IpAddr() {}
  constexpr IpAddr(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e,
                   uint16_t f, uint16_t g, uint16_t h, uint16_t port)
      : ipv6{.sin6_family = AF_INET6,
             .sin6_addr = {{{
                 static_cast<unsigned char>(a >> 8),
                 static_cast<unsigned char>(a & 0xff),
                 static_cast<unsigned char>(b >> 8),
                 static_cast<unsigned char>(b & 0xff),
                 static_cast<unsigned char>(c >> 8),
                 static_cast<unsigned char>(c & 0xff),
                 static_cast<unsigned char>(d >> 8),
                 static_cast<unsigned char>(d & 0xff),
                 static_cast<unsigned char>(e >> 8),
                 static_cast<unsigned char>(e & 0xff),
                 static_cast<unsigned char>(f >> 8),
                 static_cast<unsigned char>(f & 0xff),
                 static_cast<unsigned char>(g >> 8),
                 static_cast<unsigned char>(g & 0xff),
                 static_cast<unsigned char>(h >> 8),
                 static_cast<unsigned char>(h & 0xff),
             }}},
             .sin6_port = uint16_t((port >> 8) | (port << 8))} {}
  constexpr IpAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port)
      : ipv4{.sin_family = AF_INET,
             .sin_addr = {(uint32_t(d) << 24) | (uint32_t(c) << 16) |
                          (uint32_t(b) << 8) | uint32_t(a)},
             .sin_port = uint16_t((port >> 8) | (port << 8))} {}
};

std::ostream& operator<<(std::ostream& out, IpAddr addr);

class HashIpAddr {
 public:
  size_t operator()(const IpAddr& addr) const;
};

class EqIpAddr {
 public:
  bool operator()(const IpAddr& a, const IpAddr& b) const;
};

inline bool operator==(const IpAddr& a, const IpAddr& b) {
  return EqIpAddr()(a, b);
}

}  // namespace overnet
