// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/win32/socket_internal.h"

#include <winsock2.h>

#include "starboard/common/log.h"
#include "starboard/memory.h"

namespace starboard {
namespace shared {
namespace win32 {

namespace {
const socklen_t kAddressStructLengthIpv4 =
    static_cast<socklen_t>(sizeof(struct sockaddr_in));
const socklen_t kAddressStructLengthIpv6 =
    static_cast<socklen_t>(sizeof(struct sockaddr_in6));
}  // namespace

SbSocketError TranslateSocketErrorStatus(int error) {
  switch (error) {
    case 0:
      return kSbSocketOk;

    // Microsoft Winsock error codes:
    //   https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
    case WSAEINPROGRESS:
    case WSAEWOULDBLOCK:
      return kSbSocketPending;
    case WSAECONNRESET:
    case WSAENETRESET:
    case WSAECONNABORTED:
      return kSbSocketErrorConnectionReset;

    // Microsoft System Error codes:
    //   https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
    case ERROR_BROKEN_PIPE:
      return kSbSocketErrorConnectionReset;
  }

  // Here's where we would be more nuanced if we need to be.
  return kSbSocketErrorFailed;
}

bool SetBooleanSocketOption(SbSocket socket,
                            int level,
                            int option_code,
                            const char* option_name,
                            bool value) {
  if (!SbSocketIsValid(socket)) {
    return false;
  }

  SB_DCHECK(socket->socket_handle != INVALID_SOCKET);
  const int on = value ? 1 : 0;
  int result = setsockopt(socket->socket_handle, level, option_code,
                          reinterpret_cast<const char*>(&on), sizeof(on));
  if (result == SOCKET_ERROR) {
    int last_error = WSAGetLastError();
    SB_DLOG(ERROR) << "Failed to set " << option_name << " on socket "
                   << socket->socket_handle << ", last_error = " << last_error;
    socket->error = TranslateSocketErrorStatus(last_error);
    return false;
  }

  socket->error = kSbSocketOk;
  return true;
}

bool SetIntegerSocketOption(SbSocket socket,
                            int level,
                            int option_code,
                            const char* option_name,
                            int value) {
  if (!SbSocketIsValid(socket)) {
    return false;
  }

  SB_DCHECK(socket->socket_handle != INVALID_SOCKET);
  int result = setsockopt(socket->socket_handle, level, option_code,
                          reinterpret_cast<const char*>(&value), sizeof(value));
  if (result == SOCKET_ERROR) {
    int last_error = WSAGetLastError();
    SB_DLOG(ERROR) << "Failed to set " << option_name << " on socket "
                   << socket->socket_handle << ", last_error = " << last_error;
    socket->error = TranslateSocketErrorStatus(last_error);
    return false;
  }

  socket->error = kSbSocketOk;
  return true;
}

bool SockAddr::FromSbSocketAddress(const SbSocketAddress* address) {
  if (!address) {
    return false;
  }

  length = sizeof(storage_);
  switch (address->type) {
    case kSbSocketAddressTypeIpv4: {
      struct sockaddr_in* addr = sockaddr_in();
      length = kAddressStructLengthIpv4;
      memset(addr, 0, length);
      addr->sin_family = AF_INET;
      addr->sin_port = htons(static_cast<USHORT>(address->port));
      memcpy(&addr->sin_addr, address->address, kAddressLengthIpv4);
      break;
    }
    case kSbSocketAddressTypeIpv6: {
      struct sockaddr_in6* addr6 = sockaddr_in6();
      length = kAddressStructLengthIpv6;
      memset(addr6, 0, length);
      addr6->sin6_family = AF_INET6;
      addr6->sin6_port = htons(static_cast<USHORT>(address->port));
      memcpy(&addr6->sin6_addr, address->address, kAddressLengthIpv6);
      break;
    }
    default:
      SB_NOTREACHED() << "Unrecognized address type: " << address->type;
      return false;
  }

  return true;
}

bool SockAddr::ToSbSocketAddress(SbSocketAddress* out_address) const {
  if (!out_address) {
    return false;
  }

  // Check that we have been properly initialized.
  SB_DCHECK(length == kAddressStructLengthIpv4 ||
            length == kAddressStructLengthIpv6);

  if (family() == AF_INET) {
    const struct sockaddr_in* addr = sockaddr_in();
    if (length < kAddressStructLengthIpv4) {
      SB_NOTREACHED() << "Insufficient INET size: " << length;
      return false;
    }

    memcpy(out_address->address, &addr->sin_addr, kAddressLengthIpv4);
    out_address->port = ntohs(addr->sin_port);
    out_address->type = kSbSocketAddressTypeIpv4;
    return true;
  }

  if (family() == AF_INET6) {
    const struct sockaddr_in6* addr6 = sockaddr_in6();
    if (length < kAddressStructLengthIpv6) {
      SB_NOTREACHED() << "Insufficient INET6 size: " << length;
      return false;
    }

    memcpy(out_address->address, &addr6->sin6_addr, kAddressLengthIpv6);
    out_address->port = ntohs(addr6->sin6_port);
    out_address->type = kSbSocketAddressTypeIpv6;
    return true;
  }

  SB_NOTREACHED() << "Unrecognized address family: " << family();
  return false;
}

bool SockAddr::FromSockaddr(const struct sockaddr* sock_addr) {
  if (!sock_addr) {
    return false;
  }

  int family = sock_addr->sa_family;
  if (family == AF_INET) {
    const struct sockaddr_in* addr =
        reinterpret_cast<const struct sockaddr_in*>(sock_addr);
    *sockaddr_in() = *addr;
    length = static_cast<socklen_t>(sizeof(*addr));
    return true;
  } else if (family == AF_INET6) {
    const struct sockaddr_in6* addr =
        reinterpret_cast<const struct sockaddr_in6*>(sock_addr);
    *sockaddr_in6() = *addr;
    length = static_cast<socklen_t>(sizeof(*addr));
    return true;
  }

  SB_DLOG(WARNING) << "Unrecognized address family: " << family;
  return false;
}

}  // namespace win32
}  // namespace shared
}  // namespace starboard
