// Copyright (c) 2017, 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/sync_socket.h"

namespace dart {
namespace bin {

bool SynchronousSocket::Initialize() {
  return SocketBase::Initialize();
}

static intptr_t Create(const RawAddr& addr) {
  const intptr_t type = SOCK_STREAM;
  SOCKET s = WSASocket(addr.ss.ss_family, type, 0, NULL, 0, 0);
  return (s == INVALID_SOCKET) ? -1 : s;
}

static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
  SOCKET socket = static_cast<SOCKET>(fd);
  intptr_t result =
      connect(socket, &addr.addr, SocketAddress::GetAddrLength(addr));
  return (result == SOCKET_ERROR) ? -1 : socket;
}

intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
  intptr_t fd = Create(addr);
  return (fd < 0) ? fd : Connect(fd, addr);
}

intptr_t SynchronousSocket::Available(intptr_t fd) {
  SOCKET socket = static_cast<SOCKET>(fd);
  DWORD available;
  intptr_t result = ioctlsocket(socket, FIONREAD, &available);
  return (result == SOCKET_ERROR) ? -1 : static_cast<intptr_t>(available);
}

intptr_t SynchronousSocket::GetPort(intptr_t fd) {
  SOCKET socket = static_cast<SOCKET>(fd);
  RawAddr raw;
  socklen_t size = sizeof(raw);
  if (getsockname(socket, &raw.addr, &size) == SOCKET_ERROR) {
    return 0;
  }
  return SocketAddress::GetAddrPort(raw);
}

SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
  SOCKET socket = static_cast<SOCKET>(fd);
  RawAddr raw;
  socklen_t size = sizeof(raw);
  if (getpeername(socket, &raw.addr, &size)) {
    return NULL;
  }
  *port = SocketAddress::GetAddrPort(raw);
  // Clear the port before calling WSAAddressToString as WSAAddressToString
  // includes the port in the formatted string.
  SocketAddress::SetAddrPort(&raw, 0);
  return new SocketAddress(&raw.addr);
}

intptr_t SynchronousSocket::Read(intptr_t fd,
                                 void* buffer,
                                 intptr_t num_bytes) {
  SOCKET socket = static_cast<SOCKET>(fd);
  return recv(socket, reinterpret_cast<char*>(buffer), num_bytes, 0);
}

intptr_t SynchronousSocket::Write(intptr_t fd,
                                  const void* buffer,
                                  intptr_t num_bytes) {
  SOCKET socket = static_cast<SOCKET>(fd);
  return send(socket, reinterpret_cast<const char*>(buffer), num_bytes, 0);
}

void SynchronousSocket::ShutdownRead(intptr_t fd) {
  SOCKET socket = static_cast<SOCKET>(fd);
  shutdown(socket, SD_RECEIVE);
}

void SynchronousSocket::ShutdownWrite(intptr_t fd) {
  SOCKET socket = static_cast<SOCKET>(fd);
  shutdown(socket, SD_SEND);
}

void SynchronousSocket::Close(intptr_t fd) {
  SOCKET socket = static_cast<SOCKET>(fd);
  closesocket(socket);
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_WINDOWS)
