//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Unittests for getsockname and getpeername.
///
//===----------------------------------------------------------------------===//

#include "hdr/sys_socket_macros.h"
#include "hdr/types/sa_family_t.h"
#include "hdr/types/socklen_t.h"
#include "hdr/types/struct_sockaddr_un.h"
#include "src/__support/CPP/scope.h"
#include "src/stdio/remove.h"
#include "src/sys/socket/accept.h"
#include "src/sys/socket/bind.h"
#include "src/sys/socket/connect.h"
#include "src/sys/socket/getpeername.h"
#include "src/sys/socket/getsockname.h"
#include "src/sys/socket/listen.h"
#include "src/sys/socket/socket.h"
#include "src/unistd/close.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/src/sys/socket/linux/socket_test_support.h"

using LIBC_NAMESPACE::testing::make_sockaddr_un;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
using LlvmLibcSockNameTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
using LIBC_NAMESPACE::cpp::scope_exit;

TEST_F(LlvmLibcSockNameTest, GetSockNameAndPeerName) {
  LIBC_NAMESPACE::testing::TestDirectoryScope dir_scope;
  // 1. Invalid Socket
  struct sockaddr_un addr;
  socklen_t addr_len = sizeof(addr);
  ASSERT_THAT(LIBC_NAMESPACE::getsockname(
                  -1, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
              Fails(EBADF));
  ASSERT_THAT(LIBC_NAMESPACE::getpeername(
                  -1, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
              Fails(EBADF));

  // 2. Unbound Socket
  int sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_STREAM, 0);
  ASSERT_GE(sock, 0);
  ASSERT_ERRNO_SUCCESS();
  scope_exit close_sock(
      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(sock), Succeeds(0)); });

  // getsockname on unbound socket should succeed
  addr_len = sizeof(addr);
  ASSERT_THAT(LIBC_NAMESPACE::getsockname(
                  sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
              Succeeds(0));
  ASSERT_GE(addr_len, static_cast<socklen_t>(sizeof(sa_family_t)));
  ASSERT_EQ(addr.sun_family, static_cast<sa_family_t>(AF_UNIX));

  // getpeername on unbound/unconnected socket should fail with ENOTCONN
  addr_len = sizeof(addr);
  ASSERT_THAT(LIBC_NAMESPACE::getpeername(
                  sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
              Fails(ENOTCONN));

  // 3. Connected Sockets
  constexpr char CLIENT_PATH[] = "getsockname_client.test";
  struct sockaddr_un client_addr;
  ASSERT_TRUE(make_sockaddr_un(CLIENT_PATH, client_addr));

  constexpr char SERVER_PATH[] = "getsockname_server.test";
  struct sockaddr_un server_addr;
  ASSERT_TRUE(make_sockaddr_un(SERVER_PATH, server_addr));

  int server_sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_STREAM, 0);
  ASSERT_GE(server_sock, 0);
  ASSERT_ERRNO_SUCCESS();
  scope_exit close_server_sock(
      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(server_sock), Succeeds(0)); });

  ASSERT_THAT(LIBC_NAMESPACE::bind(
                  server_sock,
                  reinterpret_cast<const struct sockaddr *>(&server_addr),
                  sizeof(struct sockaddr_un)),
              Succeeds(0));
  scope_exit remove_server_path(
      [&] { ASSERT_THAT(LIBC_NAMESPACE::remove(SERVER_PATH), Succeeds(0)); });

  ASSERT_THAT(LIBC_NAMESPACE::listen(server_sock, 1), Succeeds(0));

  int client_sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_STREAM, 0);
  ASSERT_GE(client_sock, 0);
  ASSERT_ERRNO_SUCCESS();
  scope_exit close_client_sock(
      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(client_sock), Succeeds(0)); });

  ASSERT_THAT(LIBC_NAMESPACE::bind(
                  client_sock,
                  reinterpret_cast<const struct sockaddr *>(&client_addr),
                  sizeof(struct sockaddr_un)),
              Succeeds(0));
  scope_exit remove_client_path(
      [&] { ASSERT_THAT(LIBC_NAMESPACE::remove(CLIENT_PATH), Succeeds(0)); });

  ASSERT_THAT(LIBC_NAMESPACE::connect(
                  client_sock,
                  reinterpret_cast<const struct sockaddr *>(&server_addr),
                  sizeof(struct sockaddr_un)),
              Succeeds(0));

  int accepted_sock = LIBC_NAMESPACE::accept(server_sock, nullptr, nullptr);
  ASSERT_GE(accepted_sock, 0);
  ASSERT_ERRNO_SUCCESS();
  scope_exit close_accepted_sock(
      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(accepted_sock), Succeeds(0)); });

  // Test getsockname on client_sock (should be client_path)
  addr_len = sizeof(addr);
  ASSERT_THAT(
      LIBC_NAMESPACE::getsockname(
          client_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
      Succeeds(0));
  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
              LIBC_NAMESPACE::testing::MatchesAddress(CLIENT_PATH));

  // Test getpeername on client_sock (should be server_path)
  addr_len = sizeof(addr);
  ASSERT_THAT(
      LIBC_NAMESPACE::getpeername(
          client_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
      Succeeds(0));
  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
              LIBC_NAMESPACE::testing::MatchesAddress(SERVER_PATH));

  // Test getsockname on accepted_sock (should be server_path)
  addr_len = sizeof(addr);
  ASSERT_THAT(
      LIBC_NAMESPACE::getsockname(
          accepted_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
      Succeeds(0));
  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
              LIBC_NAMESPACE::testing::MatchesAddress(SERVER_PATH));

  // Test getpeername on accepted_sock (should be client_path)
  addr_len = sizeof(addr);
  ASSERT_THAT(
      LIBC_NAMESPACE::getpeername(
          accepted_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
      Succeeds(0));
  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
              LIBC_NAMESPACE::testing::MatchesAddress(CLIENT_PATH));
}
