/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmServerConnection.h"

#include "cmServerDictionary.h"

#include "cmFileMonitor.h"
#include "cmServer.h"

#include <assert.h>
#include <string.h>

namespace {

struct write_req_t
{
  uv_write_t req;
  uv_buf_t buf;
};

void on_alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
{
  (void)(handle);
  char* rawBuffer = new char[suggested_size];
  *buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
}

void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
  auto conn = reinterpret_cast<cmServerConnection*>(stream->data);
  if (nread >= 0) {
    conn->ReadData(std::string(buf->base, buf->base + nread));
  } else {
    conn->TriggerShutdown();
  }

  delete[](buf->base);
}

void on_write(uv_write_t* req, int status)
{
  (void)(status);
  auto conn = reinterpret_cast<cmServerConnection*>(req->data);

  // Free req and buffer
  write_req_t* wr = reinterpret_cast<write_req_t*>(req);
  delete[](wr->buf.base);
  delete wr;

  conn->ProcessNextRequest();
}

void on_new_connection(uv_stream_t* stream, int status)
{
  (void)(status);
  auto conn = reinterpret_cast<cmServerConnection*>(stream->data);
  conn->Connect(stream);
}

void on_signal(uv_signal_t* signal, int signum)
{
  auto conn = reinterpret_cast<cmServerConnection*>(signal->data);
  (void)(signum);
  conn->TriggerShutdown();
}

void on_signal_close(uv_handle_t* handle)
{
  delete reinterpret_cast<uv_signal_t*>(handle);
}

void on_pipe_close(uv_handle_t* handle)
{
  delete reinterpret_cast<uv_pipe_t*>(handle);
}

void on_tty_close(uv_handle_t* handle)
{
  delete reinterpret_cast<uv_tty_t*>(handle);
}

} // namespace

class LoopGuard
{
public:
  LoopGuard(cmServerConnection* connection)
    : Connection(connection)
  {
    this->Connection->mLoop = uv_default_loop();
    if (!this->Connection->mLoop) {
      return;
    }
    this->Connection->mFileMonitor =
      new cmFileMonitor(this->Connection->mLoop);
  }

  ~LoopGuard()
  {
    if (!this->Connection->mLoop) {
      return;
    }

    if (this->Connection->mFileMonitor) {
      delete this->Connection->mFileMonitor;
    }
    uv_loop_close(this->Connection->mLoop);
    this->Connection->mLoop = nullptr;
  }

private:
  cmServerConnection* Connection;
};

cmServerConnection::cmServerConnection()
{
}

cmServerConnection::~cmServerConnection()
{
}

void cmServerConnection::SetServer(cmServer* s)
{
  this->Server = s;
}

bool cmServerConnection::ProcessEvents(std::string* errorMessage)
{
  assert(this->Server);
  errorMessage->clear();

  this->RawReadBuffer.clear();
  this->RequestBuffer.clear();

  LoopGuard guard(this);
  (void)(guard);
  if (!this->mLoop) {
    *errorMessage = "Internal Error: Failed to create event loop.";
    return false;
  }

  this->SIGINTHandler = new uv_signal_t;
  uv_signal_init(this->mLoop, this->SIGINTHandler);
  this->SIGINTHandler->data = static_cast<void*>(this);
  uv_signal_start(this->SIGINTHandler, &on_signal, SIGINT);

  this->SIGHUPHandler = new uv_signal_t;
  uv_signal_init(this->mLoop, this->SIGHUPHandler);
  this->SIGHUPHandler->data = static_cast<void*>(this);
  uv_signal_start(this->SIGHUPHandler, &on_signal, SIGHUP);

  if (!DoSetup(errorMessage)) {
    return false;
  }

  if (uv_run(this->mLoop, UV_RUN_DEFAULT) != 0) {
    *errorMessage = "Internal Error: Event loop stopped in unclean state.";
    return false;
  }

  // These need to be cleaned up by now:
  assert(!this->ReadStream);
  assert(!this->WriteStream);

  this->RawReadBuffer.clear();
  this->RequestBuffer.clear();

  return true;
}

void cmServerConnection::ReadData(const std::string& data)
{
  this->RawReadBuffer += data;

  for (;;) {
    auto needle = this->RawReadBuffer.find('\n');

    if (needle == std::string::npos) {
      return;
    }
    std::string line = this->RawReadBuffer.substr(0, needle);
    const auto ls = line.size();
    if (ls > 1 && line.at(ls - 1) == '\r') {
      line.erase(ls - 1, 1);
    }
    this->RawReadBuffer.erase(this->RawReadBuffer.begin(),
                              this->RawReadBuffer.begin() +
                                static_cast<long>(needle) + 1);
    if (line == kSTART_MAGIC) {
      this->RequestBuffer.clear();
      continue;
    }
    if (line == kEND_MAGIC) {
      this->Server->QueueRequest(this->RequestBuffer);
      this->RequestBuffer.clear();
    } else {
      this->RequestBuffer += line;
      this->RequestBuffer += "\n";
    }
  }
}

void cmServerConnection::TriggerShutdown()
{
  this->FileMonitor()->StopMonitoring();

  uv_signal_stop(this->SIGINTHandler);
  uv_signal_stop(this->SIGHUPHandler);

  uv_close(reinterpret_cast<uv_handle_t*>(this->SIGINTHandler),
           &on_signal_close); // delete handle
  uv_close(reinterpret_cast<uv_handle_t*>(this->SIGHUPHandler),
           &on_signal_close); // delete handle

  this->SIGINTHandler = nullptr;
  this->SIGHUPHandler = nullptr;

  this->TearDown();
}

void cmServerConnection::WriteData(const std::string& data)
{
  assert(this->WriteStream);

  auto ds = data.size();

  write_req_t* req = new write_req_t;
  req->req.data = this;
  req->buf = uv_buf_init(new char[ds], static_cast<unsigned int>(ds));
  memcpy(req->buf.base, data.c_str(), ds);

  uv_write(reinterpret_cast<uv_write_t*>(req),
           static_cast<uv_stream_t*>(this->WriteStream), &req->buf, 1,
           on_write);
}

void cmServerConnection::ProcessNextRequest()
{
  Server->PopOne();
}

void cmServerConnection::SendGreetings()
{
  Server->PrintHello();
}

cmServerStdIoConnection::cmServerStdIoConnection()
{
  this->Input.tty = nullptr;
  this->Output.tty = nullptr;
}

bool cmServerStdIoConnection::DoSetup(std::string* errorMessage)
{
  (void)(errorMessage);

  if (uv_guess_handle(1) == UV_TTY) {
    usesTty = true;
    this->Input.tty = new uv_tty_t;
    uv_tty_init(this->Loop(), this->Input.tty, 0, 1);
    uv_tty_set_mode(this->Input.tty, UV_TTY_MODE_NORMAL);
    Input.tty->data = this;
    this->ReadStream = reinterpret_cast<uv_stream_t*>(this->Input.tty);

    this->Output.tty = new uv_tty_t;
    uv_tty_init(this->Loop(), this->Output.tty, 1, 0);
    uv_tty_set_mode(this->Output.tty, UV_TTY_MODE_NORMAL);
    Output.tty->data = this;
    this->WriteStream = reinterpret_cast<uv_stream_t*>(this->Output.tty);
  } else {
    usesTty = false;
    this->Input.pipe = new uv_pipe_t;
    uv_pipe_init(this->Loop(), this->Input.pipe, 0);
    uv_pipe_open(this->Input.pipe, 0);
    Input.pipe->data = this;
    this->ReadStream = reinterpret_cast<uv_stream_t*>(this->Input.pipe);

    this->Output.pipe = new uv_pipe_t;
    uv_pipe_init(this->Loop(), this->Output.pipe, 0);
    uv_pipe_open(this->Output.pipe, 1);
    Output.pipe->data = this;
    this->WriteStream = reinterpret_cast<uv_stream_t*>(this->Output.pipe);
  }

  SendGreetings();
  uv_read_start(this->ReadStream, on_alloc_buffer, on_read);

  return true;
}

void cmServerStdIoConnection::TearDown()
{
  if (usesTty) {
    uv_close(reinterpret_cast<uv_handle_t*>(this->Input.tty), &on_tty_close);
    uv_close(reinterpret_cast<uv_handle_t*>(this->Output.tty), &on_tty_close);
    this->Input.tty = nullptr;
    this->Output.tty = nullptr;
  } else {
    uv_close(reinterpret_cast<uv_handle_t*>(this->Input.pipe), &on_pipe_close);
    uv_close(reinterpret_cast<uv_handle_t*>(this->Output.pipe),
             &on_pipe_close);
    this->Input.pipe = nullptr;
    this->Input.pipe = nullptr;
  }
  this->ReadStream = nullptr;
  this->WriteStream = nullptr;
}

cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
  : PipeName(name)
{
}

bool cmServerPipeConnection::DoSetup(std::string* errorMessage)
{
  this->ServerPipe = new uv_pipe_t;
  uv_pipe_init(this->Loop(), this->ServerPipe, 0);
  this->ServerPipe->data = this;

  int r;
  if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
    *errorMessage = std::string("Internal Error with ") + this->PipeName +
      ": " + uv_err_name(r);
    return false;
  }
  auto serverStream = reinterpret_cast<uv_stream_t*>(this->ServerPipe);
  if ((r = uv_listen(serverStream, 1, on_new_connection)) != 0) {
    *errorMessage = std::string("Internal Error listening on ") +
      this->PipeName + ": " + uv_err_name(r);
    return false;
  }

  return true;
}

void cmServerPipeConnection::TearDown()
{
  if (this->ClientPipe) {
    uv_close(reinterpret_cast<uv_handle_t*>(this->ClientPipe), &on_pipe_close);
    this->WriteStream->data = nullptr;
  }
  uv_close(reinterpret_cast<uv_handle_t*>(this->ServerPipe), &on_pipe_close);

  this->ClientPipe = nullptr;
  this->ServerPipe = nullptr;
  this->WriteStream = nullptr;
  this->ReadStream = nullptr;
}

void cmServerPipeConnection::Connect(uv_stream_t* server)
{
  if (this->ClientPipe) {
    // Accept and close all pipes but the first:
    uv_pipe_t* rejectPipe = new uv_pipe_t;

    uv_pipe_init(this->Loop(), rejectPipe, 0);
    auto rejecter = reinterpret_cast<uv_stream_t*>(rejectPipe);
    uv_accept(server, rejecter);
    uv_close(reinterpret_cast<uv_handle_t*>(rejecter), &on_pipe_close);
    return;
  }

  this->ClientPipe = new uv_pipe_t;
  uv_pipe_init(this->Loop(), this->ClientPipe, 0);
  this->ClientPipe->data = this;
  auto client = reinterpret_cast<uv_stream_t*>(this->ClientPipe);
  if (uv_accept(server, client) != 0) {
    uv_close(reinterpret_cast<uv_handle_t*>(client), nullptr);
    return;
  }
  this->ReadStream = client;
  this->WriteStream = client;

  uv_read_start(this->ReadStream, on_alloc_buffer, on_read);

  this->SendGreetings();
}
