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

// These tests ensure the zircon libc can talk to netstack.
// No network connection is required, only a running netstack binary.

#include "util.h"

#include <thread>

#include <fuchsia/net/c/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <lib/sync/completion.h>
#include <zircon/status.h>

#include <zircon/syscalls.h>

#include "gtest/gtest.h"

zx_handle_t GetHandle(int fd) {
  fdio_t* io;
  zx_status_t status = fdio_unbind_from_fd(fd, &io);
  EXPECT_EQ(status, ZX_OK) << zx_status_get_string(status);
  zx_handle_t h;
  zx_signals_t sigs;
  fdio_unsafe_wait_begin(io, 0, &h, &sigs);
  EXPECT_NE(h, ZX_HANDLE_INVALID);
  fdio_unsafe_release(io);
  return h;
}

TEST(NetStreamTest, BlockingAcceptWriteNoClose) {
  short port = 0;  // will be assigned by the first bind.

  for (int j = 0; j < 2; j++) {
    int acptfd = socket(AF_INET, SOCK_STREAM, 0);
    ASSERT_GE(acptfd, 0);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = port;
    addr.sin_addr.s_addr = INADDR_ANY;

    int ret = 0;
    for (int retry = 0; retry < 2; retry++) {
      ret = bind(acptfd, (const struct sockaddr*)&addr, sizeof(addr));
      if (j > 0 && ret < 0 && errno == EADDRINUSE) {
        // Wait until netstack detects the peer handle is closed and
        // tears down the port.
        zx_nanosleep(zx_deadline_after(ZX_MSEC(10)));
      } else {
        break;
      }
    }
    ASSERT_EQ(0, ret) << "bind failed: " << errno << " port: " << port;

    socklen_t addrlen = sizeof(addr);
    ret = getsockname(acptfd, (struct sockaddr*)&addr, &addrlen);
    ASSERT_EQ(0, ret) << "getsockname failed: " << errno;

    // remember the assigned port and use it for the next bind.
    port = addr.sin_port;

    int ntfyfd[2];
    ASSERT_EQ(0, pipe(ntfyfd));

    ret = listen(acptfd, 10);
    ASSERT_EQ(0, ret) << "listen failed: " << errno;

    std::string out;
    std::thread thrd(StreamConnectRead, &addr, &out, ntfyfd[1]);

    int connfd = accept(acptfd, nullptr, nullptr);
    ASSERT_GE(connfd, 0) << "accept failed: " << errno;

    const char* msg = "hello";
    ASSERT_EQ((ssize_t)strlen(msg), write(connfd, msg, strlen(msg)));
    ASSERT_EQ(0, close(connfd));

    ASSERT_EQ(true, WaitSuccess(ntfyfd[0], kTimeout));
    thrd.join();

    EXPECT_STREQ(msg, out.c_str());

    // Simulate unexpected process exit by closing the socket handle
    // without sending a Close op to netstack.
    zx_handle_close(GetHandle(acptfd));

    EXPECT_EQ(0, close(ntfyfd[0]));
    EXPECT_EQ(0, close(ntfyfd[1]));
  }
}

TEST(NetStreamTest, RaceClose) {
  int fd = socket(AF_INET, SOCK_STREAM, 0);
  ASSERT_GE(fd, 0) << strerror(errno);

  zx_handle_t h = GetHandle(fd);

  sync_completion_t completion;

  std::vector<std::thread> workers;
  for (int i = 0; i < 10; i++) {
    workers.push_back(std::thread([&h, &completion]() {
      ASSERT_EQ(sync_completion_wait(&completion, ZX_TIME_INFINITE), ZX_OK);

      int16_t out_code;
      zx_status_t status = fuchsia_net_SocketControlClose(h, &out_code);
      if (status == ZX_OK) {
        EXPECT_EQ(out_code, 0) << strerror(out_code);
      } else {
        EXPECT_EQ(status, ZX_ERR_PEER_CLOSED) << zx_status_get_string(status);
      }
    }));
  }

  sync_completion_signal(&completion);

  std::for_each(workers.begin(), workers.end(),
                std::mem_fn(&std::thread::join));
}
