// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quic/platform/impl/quic_socket_utils.h"

#include <fcntl.h>

#include <array>

#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_socket_address.h"
#include "net/third_party/quic/platform/api/quic_test.h"
#include "starboard/types.h"

namespace quic {
namespace test {
namespace {

// A test fixture is used to ensure that all sockets are closed down gracefully
// upon test completion.  Also provides a convenient API to Bind not presently
// available in QuicSocketUtils.
class QuicSocketUtilsTest : public QuicTest {
 protected:
  ~QuicSocketUtilsTest() override {
    for (int fd : open_sockets_) {
      close(fd);
    }
  }

  int CreateUDPSocket(const QuicSocketAddress& address) {
    bool overflow_supported = false;
    int fd = QuicSocketUtils::CreateUDPSocket(
        address, /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
        /*send_buffer_size =*/kDefaultSocketReceiveBuffer, &overflow_supported);
    if (fd != -1) {
      open_sockets_.push_back(fd);
    }
    return fd;
  }

  int CreateBoundUDPSocket(QuicSocketAddress* address) {
    int fd = CreateUDPSocket(*address);
    *address = BindSocket(fd, *address);
    if (!address->IsInitialized()) {
      close(fd);
      fd = -1;
    }
    return fd;
  }

  QuicSocketAddress BindSocket(int fd, const QuicSocketAddress& address) {
    QuicSocketAddress bound_address;

    if (fd == -1) {
      return bound_address;
    }

    sockaddr_storage bind_addr_native = address.generic_address();
    socklen_t bind_addr_size = 0;

    switch (address.host().address_family()) {
      case IpAddressFamily::IP_V4:
        bind_addr_size = sizeof(struct sockaddr_in);
        break;
      case IpAddressFamily::IP_V6:
        bind_addr_size = sizeof(struct sockaddr_in6);
        break;
      case IpAddressFamily::IP_UNSPEC:
        QUIC_LOG(FATAL) << "Unspecified IP address family";
    }

    int rc = bind(fd, reinterpret_cast<sockaddr*>(&bind_addr_native),
                  bind_addr_size);
    if (rc != 0) {
      QUIC_LOG(ERROR) << "Failed to bind socket to " << address.ToString()
                      << ": " << strerror(errno);
      return bound_address;
    }

    rc = bound_address.FromSocket(fd);
    if (rc != 0) {
      QUIC_LOG(ERROR) << "Failed to get bound socket address from fd: "
                      << strerror(errno);
      bound_address = QuicSocketAddress();
    }
    return bound_address;
  }

 private:
  std::vector<int> open_sockets_;
};

// This test verifies that QuicSocketUtils creates a non-blocking socket
// successfully by seeing if a read blocks.
TEST_F(QuicSocketUtilsTest, NonBlockingSocket) {
  std::array<char, 512> buffer;

  QuicIpAddress localhost = QuicIpAddress::Loopback4();
  QuicSocketAddress addr(localhost, 0);

  int fd = CreateUDPSocket(addr);
  ASSERT_NE(-1, fd);

  int fd_flags = fcntl(fd, F_GETFL, 0);

  // Assert so that the test errors out quickly rather than blocking below and
  // relying on timeouts.
  ASSERT_TRUE(fd_flags & O_NONBLOCK) << "Socket not reporting as non-blocking";

  QuicIpAddress target_server_addr;
  auto walltimestamp = QuicWallTime::Zero();
  QuicSocketAddress remote_addr;
  int bytes_read = QuicSocketUtils::ReadPacket(fd, buffer.data(), buffer.size(),
                                               nullptr, &target_server_addr,
                                               &walltimestamp, &remote_addr);
  EXPECT_EQ(-1, bytes_read);
}

// This test verifies that we can successfully WritePacket/ReadPacket between
// two localhost sockets.
TEST_F(QuicSocketUtilsTest, PacketRoundTrip) {
  QuicIpAddress localhost = QuicIpAddress::Loopback4();
  QuicSocketAddress client_addr(localhost, 0);
  QuicSocketAddress server_addr(localhost, 0);

  int server_fd = CreateBoundUDPSocket(&server_addr);
  int client_fd = CreateUDPSocket(client_addr);

  ASSERT_NE(-1, server_fd);
  ASSERT_NE(-1, client_fd);

  {
    std::array<char, 512> write_buffer;
    for (size_t i = 0; i < write_buffer.size(); i++) {
      write_buffer[i] = static_cast<char>(i);
    }
    auto res = QuicSocketUtils::WritePacket(client_fd, write_buffer.data(),
                                            write_buffer.size(),
                                            QuicIpAddress(), server_addr);
    ASSERT_EQ(WRITE_STATUS_OK, res.status)
        << "Failed to write with error " << res.error_code;
    EXPECT_EQ(512, res.bytes_written);
  }

  fd_set read_fds;
  FD_ZERO(&read_fds);
  FD_SET(server_fd, &read_fds);

  timeval select_timeout;
  select_timeout.tv_sec = 5;
  select_timeout.tv_usec = 0;

  int select_rc =
      select(1 + server_fd, &read_fds, nullptr, nullptr, &select_timeout);
  EXPECT_EQ(select_rc, 1) << "server_fd didn't become read selectable: "
                          << errno;

  {
    std::array<char, 1024> read_buffer;
    QuicIpAddress target_server_addr;
    auto walltimestamp = QuicWallTime::Zero();
    QuicSocketAddress remote_addr;
    int bytes_read = QuicSocketUtils::ReadPacket(
        server_fd, read_buffer.data(), read_buffer.size(), nullptr,
        &target_server_addr, &walltimestamp, &remote_addr);
    EXPECT_EQ(512, bytes_read);
    for (int i = 0; i < bytes_read; i++) {
      EXPECT_EQ(static_cast<char>(i), read_buffer[i]);
    }
  }
}

}  // namespace
}  // namespace test
}  // namespace quic
