// 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));
}

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
