// Copyright 2015 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_NPLB_SOCKET_HELPERS_H_
#define STARBOARD_NPLB_SOCKET_HELPERS_H_

#include <vector>

#include "starboard/common/scoped_ptr.h"
#include "starboard/socket.h"
#include "starboard/socket_waiter.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {

const SbTime kSocketTimeout = kSbTimeSecond / 5;

// Returns true if the given address is the unspecified address (all zeros),
// supporting both address types.
bool IsUnspecified(const SbSocketAddress* address);

// Returns true if the given address is the localhost address, supporting both
// address types.
bool IsLocalhost(const SbSocketAddress* address);

// Returns a valid port number that can be bound to for use in nplb tests.
// This will always return the same port number.
int GetPortNumberForTests();

// Returns an IP localhost address with the given port.
SbSocketAddress GetLocalhostAddress(SbSocketAddressType address_type, int port);

// Returns an IP unspecified address with the given port.
SbSocketAddress GetUnspecifiedAddress(SbSocketAddressType address_type,
                                      int port);

// Creates a TCP/IP server socket (sets Reuse Address option).
SbSocket CreateServerTcpSocket(SbSocketAddressType address_type);
scoped_ptr<Socket> CreateServerTcpSocketWrapped(
    SbSocketAddressType address_type);

// Creates a TCP/IP socket bound to all interfaces on the given port.
SbSocket CreateBoundTcpSocket(SbSocketAddressType address_type, int port);
scoped_ptr<Socket> CreateBoundTcpSocketWrapped(SbSocketAddressType address_type,
                                               int port);

// Creates a TCP/IP socket listening on all interfaces on the given port.
SbSocket CreateListeningTcpSocket(SbSocketAddressType address_type, int port);
scoped_ptr<Socket> CreateListeningTcpSocketWrapped(
    SbSocketAddressType address_type,
    int port);

// Tries to accept a new connection from the given listening socket by checking,
// yielding, and retrying for up to timeout. Returns kSbSocketInvalid if no
// socket has been accepted in the given time.
SbSocket AcceptBySpinning(SbSocket listen_socket, SbTime timeout);
scoped_ptr<Socket> AcceptBySpinning(Socket* listen_socket, SbTime timeout);

// Writes the given data to socket, spinning until success or error.
bool WriteBySpinning(SbSocket socket,
                     const char* data,
                     int data_size,
                     SbTime timeout);
bool WriteBySpinning(Socket* socket,
                     const char* data,
                     int data_size,
                     SbTime timeout);

// Reads the given amount of data from socket, spinning until success or error.
bool ReadBySpinning(SbSocket socket,
                    char* out_data,
                    int data_size,
                    SbTime timeout);
bool ReadBySpinning(Socket* socket,
                    char* out_data,
                    int data_size,
                    SbTime timeout);

// Transfers data between the two connected local sockets, spinning until |size|
// has been transfered, or an error occurs.
int Transfer(SbSocket receive_socket,
             char* out_data,
             SbSocket send_socket,
             const char* send_data,
             int size);
int Transfer(Socket* receive_socket,
             char* out_data,
             Socket* send_socket,
             const char* send_data,
             int size);

struct ConnectedTrio {
  ConnectedTrio()
      : listen_socket(kSbSocketInvalid),
        client_socket(kSbSocketInvalid),
        server_socket(kSbSocketInvalid) {}
  ConnectedTrio(SbSocket listen_socket,
                SbSocket client_socket,
                SbSocket server_socket)
      : listen_socket(listen_socket),
        client_socket(client_socket),
        server_socket(server_socket) {}
  SbSocket listen_socket;
  SbSocket client_socket;
  SbSocket server_socket;
};

struct ConnectedTrioWrapped {
  ConnectedTrioWrapped() {}
  ConnectedTrioWrapped(scoped_ptr<Socket> listen_socket,
                       scoped_ptr<Socket> client_socket,
                       scoped_ptr<Socket> server_socket)
      : listen_socket(listen_socket.Pass()),
        client_socket(client_socket.Pass()),
        server_socket(server_socket.Pass()) {}
  scoped_ptr<Socket> listen_socket;
  scoped_ptr<Socket> client_socket;
  scoped_ptr<Socket> server_socket;
};

// Creates and returns 3 TCP/IP sockets, a connected client and server, and a
// listener on the given port. If anything fails, adds a failure and returns
// three invalid sockets.
ConnectedTrio CreateAndConnect(SbSocketAddressType server_address_type,
                               SbSocketAddressType client_address_type,
                               int port,
                               SbTime timeout);
scoped_ptr<ConnectedTrioWrapped> CreateAndConnectWrapped(
    SbSocketAddressType server_address_type,
    SbSocketAddressType client_address_type,
    int port,
    SbTime timeout);

// Waits on the given waiter, and returns the elapsed time.
SbTimeMonotonic TimedWait(SbSocketWaiter waiter);

// Waits on the given waiter, and returns the elapsed time.
SbTimeMonotonic TimedWaitTimed(SbSocketWaiter waiter, SbTime timeout);

// Waits on the given waiter, and checks that it blocked between [lower, upper).
static inline void WaitShouldBlockBetween(SbSocketWaiter waiter,
                                          SbTime lower,
                                          SbTime upper) {
  SbTime time = TimedWait(waiter);
  EXPECT_GT(upper, time);
  EXPECT_LE(lower, time);
}

// Waits on the given waiter, and checks that it did not block for very long.
static inline void WaitShouldNotBlock(SbSocketWaiter waiter) {
  WaitShouldBlockBetween(waiter, 0, kSocketTimeout);
}

// Waits on the given waiter, and checks that it did not block for the given
// timeout.
static inline void TimedWaitShouldNotBlock(SbSocketWaiter waiter,
                                           SbTime timeout) {
  EXPECT_GT(timeout, TimedWaitTimed(waiter, timeout));
}

// Waits on the given waiter, and checks that it did block for at least the
// given timeout.
static inline void TimedWaitShouldBlock(SbSocketWaiter waiter, SbTime timeout) {
  EXPECT_LE(timeout, TimedWaitTimed(waiter, timeout));
}

// Socket operations may return specific (e.g. kSbSocketErrorConnectionReset) or
// general (e.g. kSbSocketErrorFailed) error codes, and while in some cases
// it may be important that we obtain a specific error message, in other cases
// it will just be used as a hint and so these methods are provided to make
// it easy to test against specific or general errors.
static inline bool SocketErrorIn(
    SbSocketError error,
    const std::vector<SbSocketError>& expected_set) {
  for (size_t i = 0; i < expected_set.size(); ++i) {
    if (expected_set[i] == error) {
      return true;
    }
  }
  return false;
}

#define EXPECT_SB_SOCKET_ERROR_IN(error, ...)        \
  do {                                               \
    EXPECT_TRUE(SocketErrorIn(error, {__VA_ARGS__})) \
        << "With " #error " = " << error;            \
  } while (false)

#define EXPECT_SB_SOCKET_ERROR_IS_ERROR(error)                          \
  do {                                                                  \
    EXPECT_FALSE(SocketErrorIn(error, {kSbSocketOk, kSbSocketPending})) \
        << "With " #error " = " << error;                               \
  } while (false)

}  // namespace nplb
}  // namespace starboard

#endif  // STARBOARD_NPLB_SOCKET_HELPERS_H_
