// Copyright 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 "platform/impl/socket_address_posix.h"

#include <cstring>
#include <vector>

#include "util/osp_logging.h"

namespace openscreen {

SocketAddressPosix::SocketAddressPosix(const struct sockaddr& address) {
  if (address.sa_family == AF_INET) {
    memcpy(&internal_address_, &address, sizeof(struct sockaddr_in));
    RecomputeEndpoint(IPAddress::Version::kV4);
  } else if (address.sa_family == AF_INET6) {
    memcpy(&internal_address_, &address, sizeof(struct sockaddr_in6));
    RecomputeEndpoint(IPAddress::Version::kV6);
  } else {
    // Not IPv4 or IPv6.
    OSP_NOTREACHED();
  }
}

SocketAddressPosix::SocketAddressPosix(const IPEndpoint& endpoint)
    : endpoint_(endpoint) {
  if (endpoint.address.IsV4()) {
    internal_address_.v4.sin_family = AF_INET;
    internal_address_.v4.sin_port = htons(endpoint.port);
    endpoint.address.CopyToV4(
        reinterpret_cast<uint8_t*>(&internal_address_.v4.sin_addr.s_addr));
  } else {
    OSP_DCHECK(endpoint.address.IsV6());

    internal_address_.v6.sin6_family = AF_INET6;
    internal_address_.v6.sin6_flowinfo = 0;
    internal_address_.v6.sin6_scope_id = 0;
    internal_address_.v6.sin6_port = htons(endpoint.port);
    endpoint.address.CopyToV6(
        reinterpret_cast<uint8_t*>(&internal_address_.v6.sin6_addr));
  }
}

struct sockaddr* SocketAddressPosix::address() {
  switch (version()) {
    case IPAddress::Version::kV4:
      return reinterpret_cast<struct sockaddr*>(&internal_address_.v4);
    case IPAddress::Version::kV6:
      return reinterpret_cast<struct sockaddr*>(&internal_address_.v6);
    default:
      OSP_NOTREACHED();
  }
}

const struct sockaddr* SocketAddressPosix::address() const {
  switch (version()) {
    case IPAddress::Version::kV4:
      return reinterpret_cast<const struct sockaddr*>(&internal_address_.v4);
    case IPAddress::Version::kV6:
      return reinterpret_cast<const struct sockaddr*>(&internal_address_.v6);
    default:
      OSP_NOTREACHED();
  }
}

socklen_t SocketAddressPosix::size() const {
  switch (version()) {
    case IPAddress::Version::kV4:
      return sizeof(struct sockaddr_in);
    case IPAddress::Version::kV6:
      return sizeof(struct sockaddr_in6);
    default:
      OSP_NOTREACHED();
  }
}

void SocketAddressPosix::RecomputeEndpoint() {
  RecomputeEndpoint(endpoint_.address.version());
}

void SocketAddressPosix::RecomputeEndpoint(IPAddress::Version version) {
  switch (version) {
    case IPAddress::Version::kV4:
      endpoint_.address = IPAddress(IPAddress::Version::kV4,
                                    reinterpret_cast<const uint8_t*>(
                                        &internal_address_.v4.sin_addr.s_addr));
      endpoint_.port = ntohs(internal_address_.v4.sin_port);
      break;
    case IPAddress::Version::kV6:
      endpoint_.address = IPAddress(IPAddress::Version::kV6,
                                    internal_address_.v6.sin6_addr.s6_addr);
      endpoint_.port = ntohs(internal_address_.v6.sin6_port);
      break;
  }
}

}  // namespace openscreen
