// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. 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/globals.h"
#if defined(DART_HOST_OS_WINDOWS)

#include "bin/socket_base.h"

#include "bin/builtin.h"
#include "bin/eventhandler.h"
#include "bin/file.h"
#include "bin/lockers.h"
#include "bin/socket_base_win.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "bin/utils_win.h"
#include "platform/syslog.h"

namespace dart {
namespace bin {

SocketAddress::SocketAddress(const RawAddr& addr) : addr_(addr) {
  if (addr.is_unnamed_unix_socket()) {
    as_string_[0] = 0;
  } else if (addr.ss.ss_family == AF_UNIX) {
    memmove(as_string_, addr.un.sun_path, sizeof(addr.un.sun_path));
  } else {
    int err = SocketBase::FormatNumericAddress(addr, as_string_,
                                               kMaxAddressStringLength);

    if (err != 0) {
      as_string_[0] = 0;
    }
  }
}

static Mutex* init_mutex = new Mutex();
static bool socket_initialized = false;

bool SocketBase::Initialize() {
  MutexLocker lock(init_mutex);
  if (socket_initialized) {
    return true;
  }
  int err;
  WSADATA winsock_data;
  WORD version_requested = MAKEWORD(2, 2);
  err = WSAStartup(version_requested, &winsock_data);
  if (err == 0) {
    socket_initialized = true;
  } else {
    Syslog::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError());
  }
  return (err == 0);
}

bool SocketBase::FormatNumericAddress(const RawAddr& addr,
                                      char* address,
                                      int len) {
  RawAddr& raw = const_cast<RawAddr&>(addr);
  wchar_t buf[SocketAddress::kMaxAddressStringLength];
  DWORD result_len = ARRAY_SIZE(buf);
  intptr_t result =
      WSAAddressToStringW(&raw.addr, raw.size, nullptr, buf, &result_len);
  if (result != 0) {
    return true;
  }
  WideToUtf8Scope wide_name(buf);
  strncpy(address, wide_name.utf8(), len);
  return false;
}

intptr_t SocketBase::Available(intptr_t fd) {
  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
  return client_socket->Available();
}

intptr_t SocketBase::Read(intptr_t fd,
                          void* buffer,
                          intptr_t num_bytes,
                          SocketOpKind sync) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  return handle->Read(buffer, num_bytes);
}

intptr_t SocketBase::RecvFrom(intptr_t fd,
                              void* buffer,
                              intptr_t num_bytes,
                              RawAddr* addr,
                              SocketOpKind sync) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  return handle->RecvFrom(buffer, num_bytes, addr);
}

bool SocketControlMessage::is_file_descriptors_control_message() {
  return false;
}

intptr_t SocketBase::ReceiveMessage(intptr_t fd,
                                    void* buffer,
                                    int64_t* p_buffer_num_bytes,
                                    SocketControlMessage** p_messages,
                                    SocketOpKind sync,
                                    OSError* p_oserror) {
  errno = ENOSYS;
  return -1;
}

bool SocketBase::AvailableDatagram(intptr_t fd,
                                   void* buffer,
                                   intptr_t num_bytes) {
  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
  return client_socket->DataReady();
}

bool SocketBase::HasPendingWrite(intptr_t fd) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  return handle->HasPendingWrite();
}

intptr_t SocketBase::Write(intptr_t fd,
                           const void* buffer,
                           intptr_t num_bytes,
                           SocketOpKind sync) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  return handle->Write(buffer, num_bytes);
}

intptr_t SocketBase::SendTo(intptr_t fd,
                            const void* buffer,
                            intptr_t num_bytes,
                            const RawAddr& addr,
                            SocketOpKind sync) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  RawAddr& raw = const_cast<RawAddr&>(addr);
  return handle->SendTo(buffer, num_bytes, raw);
}

intptr_t SocketBase::SendMessage(intptr_t fd,
                                 void* buffer,
                                 size_t num_bytes,
                                 SocketControlMessage* messages,
                                 intptr_t num_messages,
                                 SocketOpKind sync,
                                 OSError* p_oserror) {
  errno = ENOSYS;
  return -1;
}

bool SocketBase::GetSocketName(intptr_t fd, RawAddr* raw) {
  ASSERT(fd >= 0);
  ASSERT(raw != nullptr);
  return getsockname(fd, &raw->addr, &raw->size) != SOCKET_ERROR;
}

intptr_t SocketBase::GetPort(intptr_t fd) {
  ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
  SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
  RawAddr raw;
  if (getsockname(socket_handle->socket(), &raw.addr, &raw.size) ==
      SOCKET_ERROR) {
    return 0;
  }
  return SocketAddress::GetAddrPort(raw);
}

SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
  ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
  SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
  RawAddr raw;
  if (socket_handle->is_client_socket() &&
      reinterpret_cast<ClientSocket*>(fd)->PopulateRemoteAddr(raw)) {
    // `raw` was populated by `ClientSocket::PopulateRemoteAddr`.
  } else {
    if (getpeername(socket_handle->socket(), &raw.addr, &raw.size)) {
      return nullptr;
    }
  }
  *port = SocketAddress::GetAddrPort(raw);
  // Clear the port before calling WSAAddressToString as WSAAddressToString
  // includes the port in the formatted string.
  if (raw.ss.ss_family != AF_UNIX) {
    SocketAddress::SetAddrPort(&raw, 0);
  }
  return new SocketAddress(raw);
}

bool SocketBase::IsBindError(intptr_t error_number) {
  return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL ||
         error_number == WSAEINVAL;
}

void SocketBase::GetError(intptr_t fd, OSError* os_error) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error());
}

int SocketBase::GetType(intptr_t fd) {
  Handle* handle = reinterpret_cast<Handle*>(fd);
  switch (GetFileType(handle->handle())) {
    case FILE_TYPE_CHAR:
      return File::kTerminal;
    case FILE_TYPE_PIPE:
      return File::kPipe;
    case FILE_TYPE_DISK:
      return File::kFile;
    default:
      return GetLastError() == NO_ERROR ? File::kOther : -1;
  }
}

intptr_t SocketBase::GetStdioHandle(intptr_t num) {
  if (num != 0) {
    return -1;
  }
  HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
  if (handle == INVALID_HANDLE_VALUE) {
    return -1;
  }
  StdHandle* std_handle = StdHandle::Stdin(handle);
  std_handle->Retain();
  return reinterpret_cast<intptr_t>(std_handle);
}

AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
                                                      int type,
                                                      OSError** os_error) {
  Initialize();

  // Perform a name lookup for a host name.
  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = SocketAddress::FromType(type);
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_ADDRCONFIG;
  hints.ai_protocol = IPPROTO_TCP;
  struct addrinfo* info = nullptr;
  int status = getaddrinfo(host, 0, &hints, &info);
  if (status != 0) {
    // We failed, try without AI_ADDRCONFIG. This can happen when looking up
    // e.g. '::1', when there are no global IPv6 addresses.
    hints.ai_flags = 0;
    status = getaddrinfo(host, 0, &hints, &info);
  }
  if (status != 0) {
    ASSERT(*os_error == nullptr);
    DWORD error_code = WSAGetLastError();
    SetLastError(error_code);
    *os_error = new OSError();
    return nullptr;
  }
  intptr_t count = 0;
  for (struct addrinfo* c = info; c != nullptr; c = c->ai_next) {
    if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
      count++;
    }
  }
  AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
  intptr_t i = 0;
  for (struct addrinfo* c = info; c != nullptr; c = c->ai_next) {
    if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
      RawAddr raw;
      memmove(&raw.addr, c->ai_addr, c->ai_addrlen);
      raw.size = c->ai_addrlen;

      addresses->SetAt(i, new SocketAddress(raw));
      i++;
    }
  }
  freeaddrinfo(info);
  return addresses;
}

bool SocketBase::ReverseLookup(const RawAddr& addr,
                               char* host,
                               intptr_t host_len,
                               OSError** os_error) {
  ASSERT(host_len >= NI_MAXHOST);
  int status = getnameinfo(&addr.addr, addr.size, host, host_len, nullptr, 0,
                           NI_NAMEREQD);
  if (status != 0) {
    ASSERT(*os_error == nullptr);
    DWORD error_code = WSAGetLastError();
    SetLastError(error_code);
    *os_error = new OSError();
    return false;
  }
  return true;
}

bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
  int result;
  const auto system_address = Utf8ToWideChar(address);
  if (type == SocketAddress::TYPE_IPV4) {
    result = InetPton(AF_INET, system_address.get(), &addr->in.sin_addr);
  } else {
    ASSERT(type == SocketAddress::TYPE_IPV6);
    result = InetPton(AF_INET6, system_address.get(), &addr->in6.sin6_addr);
  }
  return result == 1;
}

bool SocketBase::RawAddrToString(RawAddr* addr, char* str) {
  wchar_t tmp_buffer[SocketAddress::kMaxAddressStringLength];
  if (addr->addr.sa_family == AF_INET) {
    if (InetNtop(AF_INET, &addr->in.sin_addr, tmp_buffer,
                 ARRAY_SIZE(tmp_buffer)) == nullptr) {
      return false;
    }
  } else {
    ASSERT(addr->addr.sa_family == AF_INET6);
    if (InetNtop(AF_INET6, &addr->in6.sin6_addr, tmp_buffer,
                 ARRAY_SIZE(tmp_buffer)) == nullptr) {
      return false;
    }
  }
  WideToUtf8Scope wide_to_utf8_scope(tmp_buffer);
  if (wide_to_utf8_scope.length() < SocketAddress::kMaxAddressStringLength) {
    strncpy(str, wide_to_utf8_scope.utf8(),
            SocketAddress::kMaxAddressStringLength);
    return true;
  }
  return false;
}

AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
    int type,
    OSError** os_error) {
  Initialize();

  ULONG size = 0;
  DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
                GAA_FLAG_SKIP_DNS_SERVER;
  // Query the size needed.
  int status = GetAdaptersAddresses(SocketAddress::FromType(type), flags,
                                    nullptr, nullptr, &size);
  IP_ADAPTER_ADDRESSES* addrs = nullptr;
  if (status == ERROR_BUFFER_OVERFLOW) {
    addrs = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(size));
    // Get the addresses now we have the right buffer.
    status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, nullptr,
                                  addrs, &size);
  }
  if (status != NO_ERROR) {
    ASSERT(*os_error == nullptr);
    DWORD error_code = WSAGetLastError();
    SetLastError(error_code);
    *os_error = new OSError();
    return nullptr;
  }
  intptr_t count = 0;
  for (IP_ADAPTER_ADDRESSES* a = addrs; a != nullptr; a = a->Next) {
    for (IP_ADAPTER_UNICAST_ADDRESS* u = a->FirstUnicastAddress; u != nullptr;
         u = u->Next) {
      count++;
    }
  }
  AddressList<InterfaceSocketAddress>* addresses =
      new AddressList<InterfaceSocketAddress>(count);
  intptr_t i = 0;
  for (IP_ADAPTER_ADDRESSES* a = addrs; a != nullptr; a = a->Next) {
    for (IP_ADAPTER_UNICAST_ADDRESS* u = a->FirstUnicastAddress; u != nullptr;
         u = u->Next) {
      ASSERT(type != AF_INET || a->Flags & IP_ADAPTER_IPV4_ENABLED);
      ASSERT(type != AF_INET6 || a->Flags & IP_ADAPTER_IPV6_ENABLED);
      ASSERT(a->IfIndex == a->Ipv6IfIndex ||
             !(a->Flags & IP_ADAPTER_IPV4_ENABLED) ||
             !(a->Flags & IP_ADAPTER_IPV6_ENABLED));
      addresses->SetAt(i,
                       new InterfaceSocketAddress(
                           RawAddr::FromInet4or6(u->Address.lpSockaddr),
                           StringUtilsWin::WideToUtf8(a->FriendlyName),
                           a->Ipv6IfIndex != 0 ? a->Ipv6IfIndex : a->IfIndex));
      i++;
    }
  }
  free(addrs);
  return addresses;
}

void SocketBase::Close(intptr_t fd) {
  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
  client_socket->Close();
}

bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int on;
  socklen_t len = sizeof(on);
  int err = getsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY,
                       reinterpret_cast<char*>(&on), &len);
  if (err == 0) {
    *enabled = (on == 1);
  }
  return (err == 0);
}

bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int on = enabled ? 1 : 0;
  return setsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY,
                    reinterpret_cast<char*>(&on), sizeof(on)) == 0;
}

bool SocketBase::GetMulticastLoop(intptr_t fd,
                                  intptr_t protocol,
                                  bool* enabled) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  uint8_t on;
  socklen_t len = sizeof(on);
  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
                                                     : IPV6_MULTICAST_LOOP;
  if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&on),
                 &len) == 0) {
    *enabled = (on == 1);
    return true;
  }
  return false;
}

bool SocketBase::SetMulticastLoop(intptr_t fd,
                                  intptr_t protocol,
                                  bool enabled) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int on = enabled ? 1 : 0;
  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
                                                     : IPV6_MULTICAST_LOOP;
  return setsockopt(handle->socket(), level, optname,
                    reinterpret_cast<char*>(&on), sizeof(on)) == 0;
}

bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  uint8_t v;
  socklen_t len = sizeof(v);
  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
                                                     : IPV6_MULTICAST_HOPS;
  if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&v),
                 &len) == 0) {
    *value = v;
    return true;
  }
  return false;
}

bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int v = value;
  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
                                                     : IPV6_MULTICAST_HOPS;
  return setsockopt(handle->socket(), level, optname,
                    reinterpret_cast<char*>(&v), sizeof(v)) == 0;
}

bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int on;
  socklen_t len = sizeof(on);
  int err = getsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST,
                       reinterpret_cast<char*>(&on), &len);
  if (err == 0) {
    *enabled = (on == 1);
  }
  return (err == 0);
}

bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int on = enabled ? 1 : 0;
  return setsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST,
                    reinterpret_cast<char*>(&on), sizeof(on)) == 0;
}

bool SocketBase::SetOption(intptr_t fd,
                           int level,
                           int option,
                           const char* data,
                           int length) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  return setsockopt(handle->socket(), level, option, data, length) == 0;
}

bool SocketBase::GetOption(intptr_t fd,
                           int level,
                           int option,
                           char* data,
                           unsigned int* length) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int optlen = static_cast<int>(*length);
  auto result = getsockopt(handle->socket(), level, option, data, &optlen);
  *length = static_cast<unsigned int>(optlen);
  return result == 0;
}

bool SocketBase::JoinMulticast(intptr_t fd,
                               const RawAddr& addr,
                               const RawAddr&,
                               int interfaceIndex) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
  struct group_req mreq;
  mreq.gr_interface = interfaceIndex;
  memmove(&mreq.gr_group, &addr.ss, addr.size);
  return setsockopt(handle->socket(), proto, MCAST_JOIN_GROUP,
                    reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
}

bool SocketBase::LeaveMulticast(intptr_t fd,
                                const RawAddr& addr,
                                const RawAddr&,
                                int interfaceIndex) {
  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
  int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
  struct group_req mreq;
  mreq.gr_interface = interfaceIndex;
  memmove(&mreq.gr_group, &addr.ss, addr.size);
  return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP,
                    reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_WINDOWS)
