// Copyright (c) 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 <string>

#include "base/bind.h"
#include "base/guid.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/sync_socket.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/net/port_server.h"
#include "net/base/sys_addrinfo.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_LINUX)
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#endif

namespace {

void SetOnCall(bool* called) {
  *called = true;
}

}  // namespace

TEST(PortReservationTest, Normal) {
  bool called = false;
  {
    PortReservation r(base::Bind(&SetOnCall, &called), 100);
  }
  ASSERT_TRUE(called);
}

TEST(PortReservationTest, Leak) {
  bool called = false;
  {
    PortReservation r(base::Bind(&SetOnCall, &called), 100);
    r.Leak();
  }
  ASSERT_FALSE(called);
}

TEST(PortReservationTest, MultipleLeaks) {
  bool called = false;
  {
    PortReservation r(base::Bind(&SetOnCall, &called), 100);
    r.Leak();
    r.Leak();
  }
  ASSERT_FALSE(called);
}

#if defined(OS_LINUX)
namespace {

void RunServerOnThread(const std::string& path,
                       const std::string& response,
                       base::WaitableEvent* listen_event,
                       std::string* request) {
  int server_sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  ASSERT_GE(server_sock_fd, 0);
  ASSERT_GE(fcntl(server_sock_fd, F_SETFL, O_NONBLOCK), 0);
  base::SyncSocket server_sock(server_sock_fd);

  struct sockaddr_un addr;
  memset(&addr, 0, sizeof(addr));
  addr.sun_family = AF_UNIX;
  memcpy(addr.sun_path, &path[0], path.length());
  ASSERT_EQ(0,
            bind(server_sock_fd,
                 reinterpret_cast<struct sockaddr*>(&addr),
                 sizeof(sa_family_t) + path.length()));
  ASSERT_EQ(0, listen(server_sock_fd, 1));
  listen_event->Signal();

  struct sockaddr_un  cli_addr;
  socklen_t clilen = sizeof(cli_addr);
  base::TimeTicks deadline =
      base::TimeTicks::Now() + base::TimeDelta::FromSeconds(2);
  int client_sock_fd = -1;
  while (base::TimeTicks::Now() < deadline && client_sock_fd < 0) {
    client_sock_fd = accept(
        server_sock_fd, reinterpret_cast<struct sockaddr*>(&cli_addr), &clilen);
  }
  ASSERT_GE(client_sock_fd, 0);
  base::SyncSocket sock(client_sock_fd);
  do {
    char c = 0;
    size_t rv = sock.Receive(&c, 1);
    if (!rv)
      break;
    request->push_back(c);
  } while (sock.Peek());
  sock.Send(response.c_str(), response.length());
}

std::string GenerateRandomPath() {
  std::string path = base::GenerateGUID();
  if (!path.empty()) {
    std::string pre_path;
    pre_path.push_back(0);  // Linux abstract namespace.
    path = pre_path + path;
  }
  return path;
}

}  // namespace

class PortServerTest : public testing::Test {
 public:
  PortServerTest() : thread_("server") {
    EXPECT_TRUE(thread_.Start());
  }

  void RunServer(const std::string& path,
                 const std::string& response,
                 std::string* request) {
    base::WaitableEvent listen_event(false, false);
    thread_.message_loop()->PostTask(
        FROM_HERE,
        base::Bind(
            &RunServerOnThread, path, response, &listen_event, request));
    ASSERT_TRUE(listen_event.TimedWait(base::TimeDelta::FromSeconds(5)));
  }

 private:
  base::Thread thread_;
};

TEST_F(PortServerTest, Reserve) {
  std::string path = GenerateRandomPath();
  PortServer server(path);

  std::string request;
  RunServer(path, "12345\n", &request);

  int port = 0;
  scoped_ptr<PortReservation> reservation;
  Status status = server.ReservePort(&port, &reservation);
  ASSERT_EQ(kOk, status.code()) << status.message();
  ASSERT_EQ(port, 12345);
}

TEST_F(PortServerTest, ReserveResetReserve) {
  std::string path = GenerateRandomPath();
  PortServer server(path);

  std::string request;
  RunServer(path, "12345\n", &request);

  int port = 0;
  scoped_ptr<PortReservation> reservation;
  Status status = server.ReservePort(&port, &reservation);
  ASSERT_EQ(kOk, status.code()) << status.message();
  ASSERT_EQ(port, 12345);

  reservation.reset();
  status = server.ReservePort(&port, &reservation);
  ASSERT_EQ(kOk, status.code()) << status.message();
  ASSERT_EQ(port, 12345);
}

TEST_F(PortServerTest, ReserveReserve) {
  std::string path = GenerateRandomPath();
  PortServer server(path);

  std::string request;
  RunServer(path, "12345\n", &request);

  int port = 0;
  scoped_ptr<PortReservation> reservation;
  Status status = server.ReservePort(&port, &reservation);
  ASSERT_EQ(kOk, status.code()) << status.message();
  ASSERT_EQ(port, 12345);

  RunServer(path, "12346\n", &request);
  status = server.ReservePort(&port, &reservation);
  ASSERT_EQ(kOk, status.code()) << status.message();
  ASSERT_EQ(port, 12346);
}
#endif

TEST(PortManagerTest, ReservePort) {
  PortManager mgr(15000, 16000);
  int port = 0;
  scoped_ptr<PortReservation> reservation;
  Status status = mgr.ReservePort(&port, &reservation);
  ASSERT_EQ(kOk, status.code()) << status.message();

  ASSERT_GE(port, 15000);
  ASSERT_LE(port, 16000);
  ASSERT_TRUE(reservation);
}

TEST(PortManagerTest, ReservePortFromPool) {
  PortManager mgr(15000, 16000);
  int first_port = 0, port = 1;
  for (int i = 0; i < 10; i++) {
    scoped_ptr<PortReservation> reservation;
    Status status = mgr.ReservePortFromPool(&port, &reservation);
    ASSERT_EQ(kOk, status.code()) << status.message();
    ASSERT_TRUE(reservation);
    ASSERT_GE(port, 15000);
    ASSERT_LE(port, 16000);
    if (i == 0)
      first_port = port;
    ASSERT_EQ(port, first_port);
  }
}
