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

#include <cassert>
#include <istream> // IWYU pragma: keep
#include <iterator>
#include <utility>

#include <cm/memory>

#include <cm3p/uv.h>

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

struct cmUVProcessChain::InternalData
{
  struct BasicStreamData
  {
    cmUVStreambuf Streambuf;
    cm::uv_pipe_ptr BuiltinStream;
    uv_stdio_container_t Stdio;
  };

  template <typename IOStream>
  struct StreamData : public BasicStreamData
  {
    StreamData()
      : BuiltinIOStream(&this->Streambuf)
    {
    }

    IOStream BuiltinIOStream;

    IOStream* GetBuiltinStream()
    {
      if (this->BuiltinStream.get()) {
        return &this->BuiltinIOStream;
      }
      return nullptr;
    }
  };

  struct ProcessData
  {
    cmUVProcessChain::InternalData* Data;
    cm::uv_process_ptr Process;
    cm::uv_pipe_ptr OutputPipe;
    bool Finished = false;
    Status ProcessStatus;
  };

  const cmUVProcessChainBuilder* Builder = nullptr;

  bool Valid = false;

  cm::uv_loop_ptr Loop;

  StreamData<std::istream> OutputStreamData;
  StreamData<std::istream> ErrorStreamData;

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

  bool Prepare(const cmUVProcessChainBuilder* builder);
  bool AddCommand(const cmUVProcessChainBuilder::ProcessConfiguration& config,
                  bool first, bool last);
  bool Finish();

  static const Status* GetStatus(const ProcessData& data);
};

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:
      // FIXME
      break;

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

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

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

  for (auto it = this->Processes.begin(); it != this->Processes.end(); ++it) {
    if (!chain.Data->AddCommand(*it, it == this->Processes.begin(),
                                it == std::prev(this->Processes.end()))) {
      return chain;
    }
  }

  chain.Data->Finish();

  return chain;
}

const cmUVProcessChain::Status* cmUVProcessChain::InternalData::GetStatus(
  const cmUVProcessChain::InternalData::ProcessData& data)
{
  if (data.Finished) {
    return &data.ProcessStatus;
  }
  return nullptr;
}

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

  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:
      outputData.BuiltinStream.init(*this->Loop, 0);
      outputData.Stdio.flags =
        static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
      outputData.Stdio.data.stream = outputData.BuiltinStream;
      break;

    case cmUVProcessChainBuilder::External:
      outputData.Stdio.flags = UV_INHERIT_FD;
      outputData.Stdio.data.fd = output.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.init(*this->Loop, 0);
      if (uv_pipe_open(errorData.BuiltinStream, pipeFd[0]) < 0) {
        return false;
      }
      errorData.Stdio.flags = UV_INHERIT_FD;
      errorData.Stdio.data.fd = pipeFd[1];
      break;
    }

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

  return true;
}

bool cmUVProcessChain::InternalData::AddCommand(
  const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
  bool last)
{
  this->Processes.emplace_back(cm::make_unique<ProcessData>());
  auto& process = *this->Processes.back();
  process.Data = this;

  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;

  std::array<uv_stdio_container_t, 3> stdio;
  stdio[0] = uv_stdio_container_t();
  if (first) {
    stdio[0].flags = UV_IGNORE;
  } else {
    assert(this->Processes.size() >= 2);
    auto& prev = *this->Processes[this->Processes.size() - 2];
    stdio[0].flags = UV_INHERIT_STREAM;
    stdio[0].data.stream = prev.OutputPipe;
  }
  if (last) {
    stdio[1] = this->OutputStreamData.Stdio;
  } else {
    if (process.OutputPipe.init(*this->Loop, 0) < 0) {
      return false;
    }
    stdio[1] = uv_stdio_container_t();
    stdio[1].flags =
      static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
    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->Finished = true;
    processData->ProcessStatus.ExitStatus = exitStatus;
    processData->ProcessStatus.TermSignal = termSignal;
    processData->Data->ProcessesCompleted++;
  };

  return process.Process.spawn(*this->Loop, options, &process) >= 0;
}

bool cmUVProcessChain::InternalData::Finish()
{
  if (this->Builder->Stdio[cmUVProcessChainBuilder::Stream_OUTPUT].Type ==
      cmUVProcessChainBuilder::Builtin) {
    this->OutputStreamData.Streambuf.open(
      this->OutputStreamData.BuiltinStream);
  }

  if (this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR].Type ==
      cmUVProcessChainBuilder::Builtin) {
    cm::uv_pipe_ptr tmpPipe;
    if (tmpPipe.init(*this->Loop, 0) < 0) {
      return false;
    }
    if (uv_pipe_open(tmpPipe, this->ErrorStreamData.Stdio.data.fd) < 0) {
      return false;
    }
    tmpPipe.reset();

    this->ErrorStreamData.Streambuf.open(this->ErrorStreamData.BuiltinStream);
  }

  this->Valid = true;
  return 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;
}

std::istream* cmUVProcessChain::OutputStream()
{
  return this->Data->OutputStreamData.GetBuiltinStream();
}

std::istream* cmUVProcessChain::ErrorStream()
{
  return this->Data->ErrorStreamData.GetBuiltinStream();
}

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

bool cmUVProcessChain::Wait(int64_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
{
  auto const& process = *this->Data->Processes[index];
  if (process.Finished) {
    return &process.ProcessStatus;
  }
  return nullptr;
}
