// Copyright 2022 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 "quiche/quic/core/io/socket.h"

#include <cerrno>
#include <climits>
#include <cstddef>

#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/quic/core/io/socket_internal.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/common/platform/api/quiche_logging.h"

#if defined(_WIN32)
#include "quiche/quic/core/io/socket_win.inc"
#else
#include "quiche/quic/core/io/socket_posix.inc"
#endif

namespace quic {
namespace socket_api {

namespace {

absl::StatusOr<AcceptResult> AcceptInternal(SocketFd fd) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);

  sockaddr_storage peer_addr;
  PlatformSocklen peer_addr_len = sizeof(peer_addr);
  SocketFd connection_socket = SyscallAccept(
      fd, reinterpret_cast<struct sockaddr*>(&peer_addr), &peer_addr_len);

  if (connection_socket == kInvalidSocketFd) {
    absl::Status status = LastSocketOperationError("::accept()");
    QUICHE_DVLOG(1) << "Failed to accept connection from socket " << fd
                    << " with error: " << status;
    return status;
  }

  absl::StatusOr<QuicSocketAddress> peer_address =
      ValidateAndConvertAddress(peer_addr, peer_addr_len);

  if (peer_address.ok()) {
    return AcceptResult{connection_socket, *peer_address};
  } else {
    return peer_address.status();
  }
}

absl::Status SetSockOptInt(SocketFd fd, int level, int option, int value) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);

  int result = SyscallSetsockopt(fd, level, option, &value, sizeof(value));

  if (result >= 0) {
    return absl::OkStatus();
  } else {
    absl::Status status = LastSocketOperationError("::setsockopt()");
    QUICHE_DVLOG(1) << "Failed to set socket " << fd << " option " << option
                    << " to " << value << " with error: " << status;
    return status;
  }
}

}  // namespace

absl::Status SetReceiveBufferSize(SocketFd fd, QuicByteCount size) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK_LE(size, QuicByteCount{INT_MAX});

  return SetSockOptInt(fd, SOL_SOCKET, SO_RCVBUF, static_cast<int>(size));
}

absl::Status SetSendBufferSize(SocketFd fd, QuicByteCount size) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK_LE(size, QuicByteCount{INT_MAX});

  return SetSockOptInt(fd, SOL_SOCKET, SO_SNDBUF, static_cast<int>(size));
}

absl::Status Connect(SocketFd fd, const QuicSocketAddress& peer_address) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK(peer_address.IsInitialized());

  sockaddr_storage addr = peer_address.generic_address();
  PlatformSocklen addrlen = GetAddrlen(peer_address.host().address_family());

  int connect_result =
      SyscallConnect(fd, reinterpret_cast<sockaddr*>(&addr), addrlen);

  if (connect_result >= 0) {
    return absl::OkStatus();
  } else {
    // For ::connect(), only `EINPROGRESS` indicates unavailable.
    absl::Status status =
        LastSocketOperationError("::connect()", /*unavailable_error_numbers=*/
                                 {EINPROGRESS});
    QUICHE_DVLOG(1) << "Failed to connect socket " << fd
                    << " to address: " << peer_address.ToString()
                    << " with error: " << status;
    return status;
  }
}

absl::Status GetSocketError(SocketFd fd) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);

  int socket_error = 0;
  PlatformSocklen len = sizeof(socket_error);
  int sockopt_result =
      SyscallGetsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_error, &len);

  if (sockopt_result >= 0) {
    if (socket_error == 0) {
      return absl::OkStatus();
    } else {
      return ToStatus(socket_error, "SO_ERROR");
    }
  } else {
    absl::Status status = LastSocketOperationError("::getsockopt()");
    QUICHE_LOG_FIRST_N(ERROR, 100)
        << "Failed to get socket error information from socket " << fd
        << " with error: " << status;
    return status;
  }
}

absl::Status Bind(SocketFd fd, const QuicSocketAddress& address) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK(address.IsInitialized());

  sockaddr_storage addr = address.generic_address();
  PlatformSocklen addr_len = GetAddrlen(address.host().address_family());

  int result = SyscallBind(fd, reinterpret_cast<sockaddr*>(&addr), addr_len);

  if (result >= 0) {
    return absl::OkStatus();
  } else {
    absl::Status status = LastSocketOperationError("::bind()");
    QUICHE_DVLOG(1) << "Failed to bind socket " << fd
                    << " to address: " << address.ToString()
                    << " with error: " << status;
    return status;
  }
}

absl::StatusOr<QuicSocketAddress> GetSocketAddress(SocketFd fd) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);

  sockaddr_storage addr;
  PlatformSocklen addr_len = sizeof(addr);

  int result =
      SyscallGetsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len);

  if (result >= 0) {
    return ValidateAndConvertAddress(addr, addr_len);
  } else {
    absl::Status status = LastSocketOperationError("::getsockname()");
    QUICHE_DVLOG(1) << "Failed to get socket " << fd
                    << " name with error: " << status;
    return status;
  }
}

absl::Status Listen(SocketFd fd, int backlog) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK_GT(backlog, 0);

  int result = SyscallListen(fd, backlog);

  if (result >= 0) {
    return absl::OkStatus();
  } else {
    absl::Status status = LastSocketOperationError("::listen()");
    QUICHE_DVLOG(1) << "Failed to mark socket: " << fd
                    << " to listen with error :" << status;
    return status;
  }
}

absl::StatusOr<AcceptResult> Accept(SocketFd fd, bool blocking) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);

#if defined(HAS_ACCEPT4)
  if (!blocking) {
    return AcceptWithFlags(fd, SOCK_NONBLOCK);
  }
#endif

  absl::StatusOr<AcceptResult> accept_result = AcceptInternal(fd);
  if (!accept_result.ok() || blocking) {
    return accept_result;
  }

#if !defined(__linux__) || !defined(SOCK_NONBLOCK)
  // If non-blocking could not be set directly on socket acceptance, need to
  // do it now.
  absl::Status set_non_blocking_result =
      SetSocketBlocking(accept_result->fd, /*blocking=*/false);
  if (!set_non_blocking_result.ok()) {
    QUICHE_LOG_FIRST_N(ERROR, 100)
        << "Failed to set socket " << fd << " as non-blocking on acceptance.";
    if (!Close(accept_result->fd).ok()) {
      QUICHE_LOG_FIRST_N(ERROR, 100)
          << "Failed to close socket " << accept_result->fd
          << " after error setting non-blocking on acceptance.";
    }
    return set_non_blocking_result;
  }
#endif

  return accept_result;
}

absl::StatusOr<absl::Span<char>> Receive(SocketFd fd, absl::Span<char> buffer,
                                         bool peek) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK(!buffer.empty());

  PlatformSsizeT num_read = SyscallRecv(fd, buffer.data(), buffer.size(),
                                        /*flags=*/peek ? MSG_PEEK : 0);

  if (num_read > 0 && static_cast<size_t>(num_read) > buffer.size()) {
    QUICHE_LOG_FIRST_N(WARNING, 100)
        << "Received more bytes (" << num_read << ") from socket " << fd
        << " than buffer size (" << buffer.size() << ").";
    return absl::OutOfRangeError(
        "::recv(): Received more bytes than buffer size.");
  } else if (num_read >= 0) {
    return buffer.subspan(0, num_read);
  } else {
    absl::Status status = LastSocketOperationError("::recv()");
    QUICHE_DVLOG(1) << "Failed to receive from socket: " << fd
                    << " with error: " << status;
    return status;
  }
}

absl::StatusOr<absl::string_view> Send(SocketFd fd, absl::string_view buffer) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK(!buffer.empty());

  PlatformSsizeT num_sent =
      SyscallSend(fd, buffer.data(), buffer.size(), /*flags=*/0);

  if (num_sent > 0 && static_cast<size_t>(num_sent) > buffer.size()) {
    QUICHE_LOG_FIRST_N(WARNING, 100)
        << "Sent more bytes (" << num_sent << ") to socket " << fd
        << " than buffer size (" << buffer.size() << ").";
    return absl::OutOfRangeError("::send(): Sent more bytes than buffer size.");
  } else if (num_sent >= 0) {
    return buffer.substr(num_sent);
  } else {
    absl::Status status = LastSocketOperationError("::send()");
    QUICHE_DVLOG(1) << "Failed to send to socket: " << fd
                    << " with error: " << status;
    return status;
  }
}

absl::StatusOr<absl::string_view> SendTo(SocketFd fd,
                                         const QuicSocketAddress& peer_address,
                                         absl::string_view buffer) {
  QUICHE_DCHECK_NE(fd, kInvalidSocketFd);
  QUICHE_DCHECK(peer_address.IsInitialized());
  QUICHE_DCHECK(!buffer.empty());

  sockaddr_storage addr = peer_address.generic_address();
  PlatformSocklen addrlen = GetAddrlen(peer_address.host().address_family());

  PlatformSsizeT num_sent =
      SyscallSendTo(fd, buffer.data(), buffer.size(),
                    /*flags=*/0, reinterpret_cast<sockaddr*>(&addr), addrlen);

  if (num_sent > 0 && static_cast<size_t>(num_sent) > buffer.size()) {
    QUICHE_LOG_FIRST_N(WARNING, 100)
        << "Sent more bytes (" << num_sent << ") to socket " << fd
        << " to address: " << peer_address.ToString() << " than buffer size ("
        << buffer.size() << ").";
    return absl::OutOfRangeError(
        "::sendto(): Sent more bytes than buffer size.");
  } else if (num_sent >= 0) {
    return buffer.substr(num_sent);
  } else {
    absl::Status status = LastSocketOperationError("::sendto()");
    QUICHE_DVLOG(1) << "Failed to send to socket: " << fd
                    << " to address: " << peer_address.ToString()
                    << " with error: " << status;
    return status;
  }
}

}  // namespace socket_api

void OwnedSocketFd::reset() {
  if (valid()) {
    absl::Status status = socket_api::Close(fd_);
    QUICHE_DLOG_IF(WARNING, !status.ok()) << "Failed to close FD: " << status;
    fd_ = kInvalidSocketFd;
  }
}

SocketFd OwnedSocketFd::release() {
  SocketFd fd = fd_;
  fd_ = kInvalidSocketFd;
  return fd;
}

}  // namespace quic
