/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <chrono>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <cm/optional>

#include <cm3p/uv.h>

#include <sys/types.h>

#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmUVHandlePtr.h"

class cmCTestRunTest;

/** \class cmProcess
 * \brief run a process with c++
 *
 * cmProcess wraps the kwsys process stuff in a c++ class.
 */
class cmProcess
{
public:
  explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner);
  ~cmProcess();
  void SetCommand(std::string const& command);
  void SetCommandArguments(std::vector<std::string> const& arg);
  void SetWorkingDirectory(std::string const& dir);
  void SetStopTimeout(cmDuration t) { this->StopTimeout = t; }
  void SetTimeout(cmDuration t) { this->Timeout = t; }
  void ChangeTimeout(cmDuration t);
  void ResetStartTime();
  // Return true if the process starts
  bool StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity);

  enum class TimeoutReason
  {
    Normal,
    StopTime,
  };
  TimeoutReason GetTimeoutReason() const { return this->TimeoutReason_; }
  struct ComputedTimeout
  {
    TimeoutReason Reason;
    cmDuration Duration;
  };
  cm::optional<ComputedTimeout> GetComputedTimeout() const;

  enum class State
  {
    Starting,
    Error,
    Exception,
    Executing,
    Exited,
    Expired,
    Killed,
    Disowned
  };

  State GetProcessStatus();
  int GetId() const { return this->Id; }
  void SetId(int id) { this->Id = id; }
  int64_t GetExitValue() const { return this->ExitValue; }
  cmDuration GetTotalTime() { return this->TotalTime; }
  std::chrono::steady_clock::time_point GetStartTime()
  {
    return this->StartTime;
  }
  std::chrono::system_clock::time_point GetSystemStartTime()
  {
    return this->SystemStartTime;
  }

  enum class Exception
  {
    None,
    Fault,
    Illegal,
    Interrupt,
    Numerical,
    Other
  };

  Exception GetExitException() const;
  std::string GetExitExceptionString() const;

  std::unique_ptr<cmCTestRunTest> GetRunner()
  {
    return std::move(this->Runner);
  }

  enum class Termination
  {
    Normal,
    Custom,
    Forced,
  };
  Termination GetTerminationStyle() const { return this->TerminationStyle; }

private:
  cm::optional<cmDuration> StopTimeout;
  cm::optional<cmDuration> Timeout;
  TimeoutReason TimeoutReason_ = TimeoutReason::Normal;
  std::chrono::steady_clock::time_point StartTime;
  std::chrono::system_clock::time_point SystemStartTime;
  cmDuration TotalTime;
  bool ReadHandleClosed = false;
  bool ProcessHandleClosed = false;

  cm::uv_process_ptr Process;
  cm::uv_pipe_ptr PipeReader;
  cm::uv_timer_ptr Timer;
  std::vector<char> Buf;

  std::unique_ptr<cmCTestRunTest> Runner;
  cmProcessOutput Conv;
  int Signal = 0;
  cmProcess::State ProcessState = cmProcess::State::Starting;

  static void OnExitCB(uv_process_t* process, int64_t exit_status,
                       int term_signal);
  static void OnTimeoutCB(uv_timer_t* timer);
  static void OnReadCB(uv_stream_t* stream, ssize_t nread,
                       uv_buf_t const* buf);
  static void OnAllocateCB(uv_handle_t* handle, size_t suggested_size,
                           uv_buf_t* buf);

  void OnExit(int64_t exit_status, int term_signal);
  void OnTimeout();
  void OnRead(ssize_t nread, uv_buf_t const* buf);
  void OnAllocate(size_t suggested_size, uv_buf_t* buf);

  void StartTimer();
  void Finish();

  class Buffer : public std::vector<char>
  {
    // Half-open index range of partial line already scanned.
    size_type First = 0;
    size_type Last = 0;

  public:
    Buffer() = default;
    bool GetLine(std::string& line);
    bool GetLast(std::string& line);
  };
  Buffer Output;
  std::string Command;
  std::string WorkingDirectory;
  std::vector<std::string> Arguments;
  std::vector<char const*> ProcessArgs;
  int Id;
  int64_t ExitValue;
  Termination TerminationStyle = Termination::Normal;
};
