// Copyright 2018 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.

#include "src/chromium/web_runner_tests/test_server.h"

#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <poll.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <zircon/compiler.h>

#include <sstream>

namespace web_runner_tests {

bool TestServer::FindAndBindPort() {
  int pipefd[2];
  if (pipe(pipefd) < 0) {
    fprintf(stderr, "pipe() failed: %d %s\n", errno, strerror(errno));
    return false;
  }
  close_[0].reset(pipefd[0]);
  close_[1].reset(pipefd[1]);

  socket_.reset(socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP));
  if (!socket_.is_valid()) {
    fprintf(stderr, "socket() failed: %d %s\n", errno, strerror(errno));
    return false;
  }

  struct sockaddr_in6 addr = {};
  addr.sin6_family = AF_INET6;
  addr.sin6_addr = in6addr_loopback;

  if (bind(socket_.get(), reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) {
    fprintf(stderr, "bind() failed: %d %s\n", errno, strerror(errno));
    return false;
  }

  socklen_t addrlen = sizeof(addr);
  if (getsockname(socket_.get(), reinterpret_cast<struct sockaddr*>(&addr), &addrlen) < 0) {
    fprintf(stderr, "getsockname() failed: %d %s\n", errno, strerror(errno));
    return false;
  }
  if (addrlen != sizeof(addr)) {
    fprintf(stderr, "getsockname() returned unexpected length %d vs %lu\n", addrlen, sizeof(addr));
    return false;
  }

  port_ = ntohs(addr.sin6_port);

  if (listen(socket_.get(), 1) < 0) {
    fprintf(stderr, "listen() failed: %d %s\n", errno, strerror(errno));
    return false;
  }

  return true;
}

void TestServer::Close() { close_[0].reset(); }

bool TestServer::Accept() {
  struct pollfd pfd[] = {
      {
          .fd = socket_.get(),
          .events = POLLIN,
      },
      {
          .fd = close_[1].get(),
          .events = POLLIN,
      },
  };
  int n = poll(pfd, countof(pfd), -1);
  if (n < 0) {
    fprintf(stderr, "poll() failed: %d %s\n", errno, strerror(errno));
    return false;
  }
  if (n == 0) {
    fprintf(stderr, "poll() returned zero with infinite timeout\n");
    return false;
  }
  if (pfd[1].revents) {
    return false;
  }
  conn_.reset(accept(socket_.get(), nullptr, nullptr));
  return conn_.is_valid();
}

bool TestServer::Read(std::string* buf) {
  ssize_t ret = read(conn_.get(), buf->data(), buf->size());
  if (ret < 0)
    return false;
  buf->resize(ret);
  return true;
}

bool TestServer::Write(const std::string& buf) {
  ssize_t ret = write(conn_.get(), buf.data(), buf.size());
  return ret == static_cast<ssize_t>(buf.size());
}

bool TestServer::WriteContent(const std::string& content) {
  std::ostringstream response;
  response << "HTTP/1.1 200 OK\r\n"
           << "Content-Length: " << content.size() << "\r\n\r\n"
           << content;
  return Write(response.str());
}

}  // namespace web_runner_tests
