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

#include "cmUVProcessChain.h"

#include <array>
#include <csignal>
#include <cstdio>
#include <istream> // IWYU pragma: keep
#include <type_traits>
#include <utility>

#include <cm/memory>

#include <cm3p/uv.h>

#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"

struct cmUVProcessChain::InternalData
{
  struct StreamData
  {
    int BuiltinStream = -1;
    uv_stdio_container_t Stdio;
  };

  struct ProcessData
  {
    cmUVProcessChain::InternalData* Data;
    cm::uv_process_ptr Process;
    cm::uv_pipe_ptr InputPipe;
    cm::uv_pipe_ptr OutputPipe;
    Status ProcessStatus;

    void Finish();
  };

  const cmUVProcessChainBuilder* Builder = nullptr;

  bool Valid = false;

  cm::uv_loop_ptr Loop;

  StreamData InputStreamData;
  StreamData OutputStreamData;
  StreamData ErrorStreamData;
  cm::uv_pipe_ptr TempOutputPipe;
  cm::uv_pipe_ptr TempErrorPipe;

  unsigned int ProcessesCompleted = 0;
  std::vector<std::unique_ptr<ProcessData>> Processes;

  bool Prepare(const cmUVProcessChainBuilder* builder);
  void SpawnProcess(
    std::size_t index,
    const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
    bool last);
  void Finish();
};

cmUVProcessChainBuilder::cmUVProcessChainBuilder()
{
  this->SetNoStream(Stream_INPUT)
    .SetNoStream(Stream_OUTPUT)
    .SetNoStream(Stream_ERROR);
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::AddCommand(
  const std::vector<std::string>& arguments)
{
  if (!arguments.empty()) {
    this->Processes.emplace_back();
    this->Processes.back().Arguments = arguments;
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetNoStream(Stream stdio)
{
  switch (stdio) {
    case Stream_INPUT:
    case Stream_OUTPUT:
    case Stream_ERROR: {
      auto& streamData = this->Stdio[stdio];
      streamData.Type = None;
      break;
    }
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetBuiltinStream(
  Stream stdio)
{
  switch (stdio) {
    case Stream_INPUT:
      // FIXME
      break;

    case Stream_OUTPUT:
    case Stream_ERROR: {
      auto& streamData = this->Stdio[stdio];
      streamData.Type = Builtin;
      break;
    }
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream(
  Stream stdio, int fd)
{
  switch (stdio) {
    case Stream_INPUT:
    case Stream_OUTPUT:
    case Stream_ERROR: {
      auto& streamData = this->Stdio[stdio];
      streamData.Type = External;
      streamData.FileDescriptor = fd;
      break;
    }
  }
  return *this;
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetMergedBuiltinStreams()
{
  this->MergedBuiltinStreams = true;
  return this->SetBuiltinStream(Stream_OUTPUT).SetBuiltinStream(Stream_ERROR);
}

cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetWorkingDirectory(
  std::string dir)
{
  this->WorkingDirectory = std::move(dir);
  return *this;
}

cmUVProcessChain cmUVProcessChainBuilder::Start() const
{
  cmUVProcessChain chain;

  if (!chain.Data->Prepare(this)) {
    return chain;
  }

  for (std::size_t i = 0; i < this->Processes.size(); i++) {
    chain.Data->SpawnProcess(i, this->Processes[i], i == 0,
                             i == this->Processes.size() - 1);
  }

  chain.Data->Finish();

  return chain;
}

bool cmUVProcessChain::InternalData::Prepare(
  const cmUVProcessChainBuilder* builder)
{
  this->Builder = builder;

  auto const& input =
    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_INPUT];
  auto& inputData = this->InputStreamData;
  switch (input.Type) {
    case cmUVProcessChainBuilder::None:
      inputData.Stdio.flags = UV_IGNORE;
      break;

    case cmUVProcessChainBuilder::Builtin: {
      // FIXME
      break;
    }

    case cmUVProcessChainBuilder::External:
      inputData.Stdio.flags = UV_INHERIT_FD;
      inputData.Stdio.data.fd = input.FileDescriptor;
      break;
  }

  auto const& error =
    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR];
  auto& errorData = this->ErrorStreamData;
  switch (error.Type) {
    case cmUVProcessChainBuilder::None:
      errorData.Stdio.flags = UV_IGNORE;
      break;

    case cmUVProcessChainBuilder::Builtin: {
      int pipeFd[2];
      if (cmGetPipes(pipeFd) < 0) {
        return false;
      }

      errorData.BuiltinStream = pipeFd[0];
      errorData.Stdio.flags = UV_INHERIT_FD;
      errorData.Stdio.data.fd = pipeFd[1];

      if (this->TempErrorPipe.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(this->TempErrorPipe, errorData.Stdio.data.fd) < 0) {
        return false;
      }

      break;
    }

    case cmUVProcessChainBuilder::External:
      errorData.Stdio.flags = UV_INHERIT_FD;
      errorData.Stdio.data.fd = error.FileDescriptor;
      break;
  }

  auto const& output =
    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_OUTPUT];
  auto& outputData = this->OutputStreamData;
  switch (output.Type) {
    case cmUVProcessChainBuilder::None:
      outputData.Stdio.flags = UV_IGNORE;
      break;

    case cmUVProcessChainBuilder::Builtin:
      if (this->Builder->MergedBuiltinStreams) {
        outputData.BuiltinStream = errorData.BuiltinStream;
        outputData.Stdio.flags = UV_INHERIT_FD;
        outputData.Stdio.data.fd = errorData.Stdio.data.fd;
      } else {
        int pipeFd[2];
        if (cmGetPipes(pipeFd) < 0) {
          return false;
        }

        outputData.BuiltinStream = pipeFd[0];
        outputData.Stdio.flags = UV_INHERIT_FD;
        outputData.Stdio.data.fd = pipeFd[1];

        if (this->TempOutputPipe.init(*this->Loop, 0) < 0) {
          return false;
        }
        if (uv_pipe_open(this->TempOutputPipe, outputData.Stdio.data.fd) < 0) {
          return false;
        }
      }
      break;

    case cmUVProcessChainBuilder::External:
      outputData.Stdio.flags = UV_INHERIT_FD;
      outputData.Stdio.data.fd = output.FileDescriptor;
      break;
  }

  bool first = true;
  for (std::size_t i = 0; i < this->Builder->Processes.size(); i++) {
    this->Processes.emplace_back(cm::make_unique<ProcessData>());
    auto& process = *this->Processes.back();
    process.Data = this;
    process.ProcessStatus.Finished = false;

    if (!first) {
      auto& prevProcess = *this->Processes[i - 1];

      int pipeFd[2];
      if (cmGetPipes(pipeFd) < 0) {
        return false;
      }

      if (prevProcess.OutputPipe.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(prevProcess.OutputPipe, pipeFd[1]) < 0) {
        return false;
      }
      if (process.InputPipe.init(*this->Loop, 0) < 0) {
        return false;
      }
      if (uv_pipe_open(process.InputPipe, pipeFd[0]) < 0) {
        return false;
      }
    }

    first = false;
  }

  return true;
}

void cmUVProcessChain::InternalData::SpawnProcess(
  std::size_t index,
  const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
  bool last)
{
  auto& process = *this->Processes[index];

  auto options = uv_process_options_t();

  // Bounds were checked at add time, first element is guaranteed to exist
  options.file = config.Arguments[0].c_str();

  std::vector<const char*> arguments;
  arguments.reserve(config.Arguments.size());
  for (auto const& arg : config.Arguments) {
    arguments.push_back(arg.c_str());
  }
  arguments.push_back(nullptr);
  options.args = const_cast<char**>(arguments.data());
  options.flags = UV_PROCESS_WINDOWS_HIDE;
  if (!this->Builder->WorkingDirectory.empty()) {
    options.cwd = this->Builder->WorkingDirectory.c_str();
  }

  std::array<uv_stdio_container_t, 3> stdio;
  if (first) {
    stdio[0] = this->InputStreamData.Stdio;
  } else {
    stdio[0] = uv_stdio_container_t();
    stdio[0].flags = UV_INHERIT_STREAM;
    stdio[0].data.stream = process.InputPipe;
  }
  if (last) {
    stdio[1] = this->OutputStreamData.Stdio;
  } else {
    stdio[1] = uv_stdio_container_t();
    stdio[1].flags = UV_INHERIT_STREAM;
    stdio[1].data.stream = process.OutputPipe;
  }
  stdio[2] = this->ErrorStreamData.Stdio;

  options.stdio = stdio.data();
  options.stdio_count = 3;
  options.exit_cb = [](uv_process_t* handle, int64_t exitStatus,
                       int termSignal) {
    auto* processData = static_cast<ProcessData*>(handle->data);
    processData->ProcessStatus.ExitStatus = exitStatus;
    processData->ProcessStatus.TermSignal = termSignal;
    processData->Finish();
  };

  if ((process.ProcessStatus.SpawnResult =
         process.Process.spawn(*this->Loop, options, &process)) < 0) {
    process.Finish();
  }
  process.InputPipe.reset();
  process.OutputPipe.reset();
}

void cmUVProcessChain::InternalData::Finish()
{
  this->TempOutputPipe.reset();
  this->TempErrorPipe.reset();
  this->Valid = true;
}

cmUVProcessChain::cmUVProcessChain()
  : Data(cm::make_unique<InternalData>())
{
  this->Data->Loop.init();
}

cmUVProcessChain::cmUVProcessChain(cmUVProcessChain&& other) noexcept
  : Data(std::move(other.Data))
{
}

cmUVProcessChain::~cmUVProcessChain() = default;

cmUVProcessChain& cmUVProcessChain::operator=(
  cmUVProcessChain&& other) noexcept
{
  this->Data = std::move(other.Data);
  return *this;
}

uv_loop_t& cmUVProcessChain::GetLoop()
{
  return *this->Data->Loop;
}

int cmUVProcessChain::OutputStream()
{
  return this->Data->OutputStreamData.BuiltinStream;
}

int cmUVProcessChain::ErrorStream()
{
  return this->Data->ErrorStreamData.BuiltinStream;
}

bool cmUVProcessChain::Valid() const
{
  return this->Data->Valid;
}

bool cmUVProcessChain::Wait(uint64_t milliseconds)
{
  bool timeout = false;
  cm::uv_timer_ptr timer;

  if (milliseconds > 0) {
    timer.init(*this->Data->Loop, &timeout);
    timer.start(
      [](uv_timer_t* handle) {
        auto* timeoutPtr = static_cast<bool*>(handle->data);
        *timeoutPtr = true;
      },
      milliseconds, 0);
  }

  while (!timeout &&
         this->Data->ProcessesCompleted < this->Data->Processes.size()) {
    uv_run(this->Data->Loop, UV_RUN_ONCE);
  }

  return !timeout;
}

std::vector<const cmUVProcessChain::Status*> cmUVProcessChain::GetStatus()
  const
{
  std::vector<const cmUVProcessChain::Status*> statuses(
    this->Data->Processes.size(), nullptr);
  for (std::size_t i = 0; i < statuses.size(); i++) {
    statuses[i] = &this->GetStatus(i);
  }
  return statuses;
}

const cmUVProcessChain::Status& cmUVProcessChain::GetStatus(
  std::size_t index) const
{
  return this->Data->Processes[index]->ProcessStatus;
}

bool cmUVProcessChain::Finished() const
{
  return this->Data->ProcessesCompleted >= this->Data->Processes.size();
}

std::pair<cmUVProcessChain::ExceptionCode, std::string>
cmUVProcessChain::Status::GetException() const
{
  if (this->SpawnResult) {
    return std::make_pair(ExceptionCode::Spawn,
                          uv_strerror(this->SpawnResult));
  }
#ifdef _WIN32
  if (this->Finished && (this->ExitStatus & 0xF0000000) == 0xC0000000) {
    // Child terminated due to exceptional behavior.
    switch (this->ExitStatus) {
      case STATUS_CONTROL_C_EXIT:
        return std::make_pair(ExceptionCode::Interrupt, "User interrupt");

      case STATUS_FLOAT_DENORMAL_OPERAND:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (denormal operand)");
      case STATUS_FLOAT_DIVIDE_BY_ZERO:
        return std::make_pair(ExceptionCode::Numerical, "Divide-by-zero");
      case STATUS_FLOAT_INEXACT_RESULT:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (inexact result)");
      case STATUS_FLOAT_INVALID_OPERATION:
        return std::make_pair(ExceptionCode::Numerical,
                              "Invalid floating-point operation");
      case STATUS_FLOAT_OVERFLOW:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point overflow");
      case STATUS_FLOAT_STACK_CHECK:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point stack check failed");
      case STATUS_FLOAT_UNDERFLOW:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point underflow");
#  ifdef STATUS_FLOAT_MULTIPLE_FAULTS
      case STATUS_FLOAT_MULTIPLE_FAULTS:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (multiple faults)");
#  endif
#  ifdef STATUS_FLOAT_MULTIPLE_TRAPS
      case STATUS_FLOAT_MULTIPLE_TRAPS:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception (multiple traps)");
#  endif
      case STATUS_INTEGER_DIVIDE_BY_ZERO:
        return std::make_pair(ExceptionCode::Numerical,
                              "Integer divide-by-zero");
      case STATUS_INTEGER_OVERFLOW:
        return std::make_pair(ExceptionCode::Numerical, "Integer overflow");

      case STATUS_DATATYPE_MISALIGNMENT:
        return std::make_pair(ExceptionCode::Fault, "Datatype misalignment");
      case STATUS_ACCESS_VIOLATION:
        return std::make_pair(ExceptionCode::Fault, "Access violation");
      case STATUS_IN_PAGE_ERROR:
        return std::make_pair(ExceptionCode::Fault, "In-page error");
      case STATUS_INVALID_HANDLE:
        return std::make_pair(ExceptionCode::Fault, "Invalid handle");
      case STATUS_NONCONTINUABLE_EXCEPTION:
        return std::make_pair(ExceptionCode::Fault,
                              "Noncontinuable exception");
      case STATUS_INVALID_DISPOSITION:
        return std::make_pair(ExceptionCode::Fault, "Invalid disposition");
      case STATUS_ARRAY_BOUNDS_EXCEEDED:
        return std::make_pair(ExceptionCode::Fault, "Array bounds exceeded");
      case STATUS_STACK_OVERFLOW:
        return std::make_pair(ExceptionCode::Fault, "Stack overflow");

      case STATUS_ILLEGAL_INSTRUCTION:
        return std::make_pair(ExceptionCode::Illegal, "Illegal instruction");
      case STATUS_PRIVILEGED_INSTRUCTION:
        return std::make_pair(ExceptionCode::Illegal,
                              "Privileged instruction");

      case STATUS_NO_MEMORY:
      default: {
        char buf[256];
        snprintf(buf, sizeof(buf), "Exit code 0x%x\n",
                 static_cast<unsigned int>(this->ExitStatus));
        return std::make_pair(ExceptionCode::Other, buf);
      }
    }
  }
#else
  if (this->Finished && this->TermSignal) {
    switch (this->TermSignal) {
#  ifdef SIGSEGV
      case SIGSEGV:
        return std::make_pair(ExceptionCode::Fault, "Segmentation fault");
#  endif
#  ifdef SIGBUS
#    if !defined(SIGSEGV) || SIGBUS != SIGSEGV
      case SIGBUS:
        return std::make_pair(ExceptionCode::Fault, "Bus error");
#    endif
#  endif
#  ifdef SIGFPE
      case SIGFPE:
        return std::make_pair(ExceptionCode::Numerical,
                              "Floating-point exception");
#  endif
#  ifdef SIGILL
      case SIGILL:
        return std::make_pair(ExceptionCode::Illegal, "Illegal instruction");
#  endif
#  ifdef SIGINT
      case SIGINT:
        return std::make_pair(ExceptionCode::Interrupt, "User interrupt");
#  endif
#  ifdef SIGABRT
      case SIGABRT:
        return std::make_pair(ExceptionCode::Other, "Subprocess aborted");
#  endif
#  ifdef SIGKILL
      case SIGKILL:
        return std::make_pair(ExceptionCode::Other, "Subprocess killed");
#  endif
#  ifdef SIGTERM
      case SIGTERM:
        return std::make_pair(ExceptionCode::Other, "Subprocess terminated");
#  endif
#  ifdef SIGHUP
      case SIGHUP:
        return std::make_pair(ExceptionCode::Other, "SIGHUP");
#  endif
#  ifdef SIGQUIT
      case SIGQUIT:
        return std::make_pair(ExceptionCode::Other, "SIGQUIT");
#  endif
#  ifdef SIGTRAP
      case SIGTRAP:
        return std::make_pair(ExceptionCode::Other, "SIGTRAP");
#  endif
#  ifdef SIGIOT
#    if !defined(SIGABRT) || SIGIOT != SIGABRT
      case SIGIOT:
        return std::make_pair(ExceptionCode::Other, "SIGIOT");
#    endif
#  endif
#  ifdef SIGUSR1
      case SIGUSR1:
        return std::make_pair(ExceptionCode::Other, "SIGUSR1");
#  endif
#  ifdef SIGUSR2
      case SIGUSR2:
        return std::make_pair(ExceptionCode::Other, "SIGUSR2");
#  endif
#  ifdef SIGPIPE
      case SIGPIPE:
        return std::make_pair(ExceptionCode::Other, "SIGPIPE");
#  endif
#  ifdef SIGALRM
      case SIGALRM:
        return std::make_pair(ExceptionCode::Other, "SIGALRM");
#  endif
#  ifdef SIGSTKFLT
      case SIGSTKFLT:
        return std::make_pair(ExceptionCode::Other, "SIGSTKFLT");
#  endif
#  ifdef SIGCHLD
      case SIGCHLD:
        return std::make_pair(ExceptionCode::Other, "SIGCHLD");
#  elif defined(SIGCLD)
      case SIGCLD:
        return std::make_pair(ExceptionCode::Other, "SIGCLD");
#  endif
#  ifdef SIGCONT
      case SIGCONT:
        return std::make_pair(ExceptionCode::Other, "SIGCONT");
#  endif
#  ifdef SIGSTOP
      case SIGSTOP:
        return std::make_pair(ExceptionCode::Other, "SIGSTOP");
#  endif
#  ifdef SIGTSTP
      case SIGTSTP:
        return std::make_pair(ExceptionCode::Other, "SIGTSTP");
#  endif
#  ifdef SIGTTIN
      case SIGTTIN:
        return std::make_pair(ExceptionCode::Other, "SIGTTIN");
#  endif
#  ifdef SIGTTOU
      case SIGTTOU:
        return std::make_pair(ExceptionCode::Other, "SIGTTOU");
#  endif
#  ifdef SIGURG
      case SIGURG:
        return std::make_pair(ExceptionCode::Other, "SIGURG");
#  endif
#  ifdef SIGXCPU
      case SIGXCPU:
        return std::make_pair(ExceptionCode::Other, "SIGXCPU");
#  endif
#  ifdef SIGXFSZ
      case SIGXFSZ:
        return std::make_pair(ExceptionCode::Other, "SIGXFSZ");
#  endif
#  ifdef SIGVTALRM
      case SIGVTALRM:
        return std::make_pair(ExceptionCode::Other, "SIGVTALRM");
#  endif
#  ifdef SIGPROF
      case SIGPROF:
        return std::make_pair(ExceptionCode::Other, "SIGPROF");
#  endif
#  ifdef SIGWINCH
      case SIGWINCH:
        return std::make_pair(ExceptionCode::Other, "SIGWINCH");
#  endif
#  ifdef SIGPOLL
      case SIGPOLL:
        return std::make_pair(ExceptionCode::Other, "SIGPOLL");
#  endif
#  ifdef SIGIO
#    if !defined(SIGPOLL) || SIGIO != SIGPOLL
      case SIGIO:
        return std::make_pair(ExceptionCode::Other, "SIGIO");
#    endif
#  endif
#  ifdef SIGPWR
      case SIGPWR:
        return std::make_pair(ExceptionCode::Other, "SIGPWR");
#  endif
#  ifdef SIGSYS
      case SIGSYS:
        return std::make_pair(ExceptionCode::Other, "SIGSYS");
#  endif
#  ifdef SIGUNUSED
#    if !defined(SIGSYS) || SIGUNUSED != SIGSYS
      case SIGUNUSED:
        return std::make_pair(ExceptionCode::Other, "SIGUNUSED");
#    endif
#  endif
      default: {
        char buf[256];
        snprintf(buf, sizeof(buf), "Signal %d", this->TermSignal);
        return std::make_pair(ExceptionCode::Other, buf);
      }
    }
  }
#endif
  return std::make_pair(ExceptionCode::None, "");
}

void cmUVProcessChain::InternalData::ProcessData::Finish()
{
  this->ProcessStatus.Finished = true;
  this->Data->ProcessesCompleted++;
}
