// 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.

#ifndef STARBOARD_SHARED_WIN32_SOCKET_INTERNAL_H_
#define STARBOARD_SHARED_WIN32_SOCKET_INTERNAL_H_

#include <WS2tcpip.h>
#include <winsock2.h>

#include "starboard/common/atomic.h"
#include "starboard/common/socket.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/win32/auto_event_handle.h"
#include "starboard/socket_waiter.h"
#include "starboard/types.h"

namespace sbwin32 = starboard::shared::win32;

struct SbSocketPrivate {
  enum struct BindTarget {
    kUnbound = 0,
    kAny = 1,
    kOther = 2,
    kAccepted = 3,
  };

  SbSocketPrivate(SbSocketAddressType address_type,
                  SbSocketProtocol protocol,
                  SOCKET handle,
                  BindTarget bound_to)
      : address_type(address_type),
        protocol(protocol),
        socket_handle(handle),
        socket_event(WSA_INVALID_EVENT),
        writable(0),
        error(kSbSocketOk),
        waiter(kSbSocketWaiterInvalid),
        bound_to(bound_to) {}
  ~SbSocketPrivate() {}

  // The address domain of this socket, IPv4 or IPv6.
  SbSocketAddressType address_type;

  // The protocol of this socket, UDP or TCP.
  SbSocketProtocol protocol;

  // The handle for this socket.
  SOCKET socket_handle;

  // The event related to the socket_handle.  Used for SbSocketWaiter.
  sbwin32::AutoEventHandle socket_event;

  // Set to true between when socket is shown as writable via WSAEventSelect/
  // WSAWaitForMultipleEvents and when writing to the socket returns
  // fails with WSAEWOULDBLOCK.
  //
  // Used to work around the fact that WSAEventSelect for FD_WRITE is
  // edge-triggered, unlike other events.
  //
  // See MSDN documentation for WSAEventSelect FD_WRITE for more info.
  starboard::atomic_bool writable;

  // The last error that occurred on this socket, or kSbSocketOk.
  SbSocketError error;

  // The waiter this socket is registered with, or kSbSocketWaiterInvalid.
  SbSocketWaiter waiter;

  BindTarget bound_to;
};

namespace starboard {
namespace shared {
namespace win32 {

const socklen_t kAddressLengthIpv4 = 4;
const socklen_t kAddressLengthIpv6 = 16;

// Translates an last_error from a socket call into an SbSocketError.
SbSocketError TranslateSocketErrorStatus(int error);

// Sets a boolean socket option, doing all appropriate checks.
bool SetBooleanSocketOption(SbSocket socket,
                            int level,
                            int option_code,
                            const char* option_name,
                            bool value);

// Sets an integer socket option, doing all appropriate checks.
bool SetIntegerSocketOption(SbSocket socket,
                            int level,
                            int option_code,
                            const char* option_name,
                            int value);

// A helper class for converting back and forth from sockaddrs, ugh.
class SockAddr {
 public:
  SockAddr() : length(sizeof(storage_)) {}
  ~SockAddr() {}

  // Initializes this SockAddr with the given SbSocketAddress, overwriting
  // anything any address previously held.
  bool FromSbSocketAddress(const SbSocketAddress* address);

  // Initializes the given SbSocketAddress with this SockAddr, which must have
  // been previously initialized.
  bool ToSbSocketAddress(SbSocketAddress* out_address) const;

  // Initializes this SockAddr with |sock_addr|, assuming it is appropriately
  // sized for its type.
  bool FromSockaddr(const struct sockaddr* sock_addr);

  // The sockaddr family. We only support INET and INET6.
  u_short family() const { return sockaddr()->sa_family; }

  struct sockaddr* sockaddr() {
    return reinterpret_cast<struct sockaddr*>(&storage_);
  }

  const struct sockaddr* sockaddr() const {
    return reinterpret_cast<const struct sockaddr*>(&storage_);
  }

  struct sockaddr_in* sockaddr_in() {
    return reinterpret_cast<struct sockaddr_in*>(&storage_);
  }

  const struct sockaddr_in* sockaddr_in() const {
    return reinterpret_cast<const struct sockaddr_in*>(&storage_);
  }

  struct sockaddr_in6* sockaddr_in6() {
    return reinterpret_cast<struct sockaddr_in6*>(&storage_);
  }

  const struct sockaddr_in6* sockaddr_in6() const {
    return reinterpret_cast<const struct sockaddr_in6*>(&storage_);
  }

  // Public on purpose, because it will be handy to be passed directly by
  // reference into other functions.
  socklen_t length;

 private:
  sockaddr_storage storage_;
};

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

#endif  // STARBOARD_SHARED_WIN32_SOCKET_INTERNAL_H_
