// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef SRC_SPAWN_SYNC_H_
#define SRC_SPAWN_SYNC_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "node_buffer.h"
#include "uv.h"
#include "v8.h"

namespace node {



class SyncProcessOutputBuffer;
class SyncProcessStdioPipe;
class SyncProcessRunner;


class SyncProcessOutputBuffer {
  static const unsigned int kBufferSize = 65536;

 public:
  inline SyncProcessOutputBuffer();

  inline void OnAlloc(size_t suggested_size, uv_buf_t* buf) const;
  inline void OnRead(const uv_buf_t* buf, size_t nread);

  inline size_t Copy(char* dest) const;

  inline unsigned int available() const;
  inline unsigned int used() const;

  inline SyncProcessOutputBuffer* next() const;
  inline void set_next(SyncProcessOutputBuffer* next);

 private:
  // Use unsigned int because that's what `uv_buf_init` takes.
  mutable char data_[kBufferSize];
  unsigned int used_ = 0;

  SyncProcessOutputBuffer* next_ = nullptr;
};


class SyncProcessStdioPipe {
  enum Lifecycle {
    kUninitialized = 0,
    kInitialized,
    kStarted,
    kClosing,
    kClosed
  };

 public:
  SyncProcessStdioPipe(SyncProcessRunner* process_handler,
                       bool readable,
                       bool writable,
                       uv_buf_t input_buffer);
  ~SyncProcessStdioPipe();

  int Initialize(uv_loop_t* loop);
  int Start();
  void Close();

  v8::Local<v8::Object> GetOutputAsBuffer(Environment* env) const;

  inline bool readable() const;
  inline bool writable() const;
  inline uv_stdio_flags uv_flags() const;

  inline uv_pipe_t* uv_pipe() const;
  inline uv_stream_t* uv_stream() const;
  inline uv_handle_t* uv_handle() const;

 private:
  inline size_t OutputLength() const;
  inline void CopyOutput(char* dest) const;

  inline void OnAlloc(size_t suggested_size, uv_buf_t* buf);
  inline void OnRead(const uv_buf_t* buf, ssize_t nread);
  inline void OnWriteDone(int result);
  inline void OnShutdownDone(int result);
  inline void OnClose();

  inline void SetError(int error);

  static void AllocCallback(uv_handle_t* handle,
                            size_t suggested_size,
                            uv_buf_t* buf);
  static void ReadCallback(uv_stream_t* stream,
                           ssize_t nread,
                           const uv_buf_t* buf);
  static void WriteCallback(uv_write_t* req, int result);
  static void ShutdownCallback(uv_shutdown_t* req, int result);
  static void CloseCallback(uv_handle_t* handle);

  SyncProcessRunner* process_handler_;

  bool readable_;
  bool writable_;
  uv_buf_t input_buffer_;

  SyncProcessOutputBuffer* first_output_buffer_;
  SyncProcessOutputBuffer* last_output_buffer_;

  mutable uv_pipe_t uv_pipe_;
  uv_write_t write_req_;
  uv_shutdown_t shutdown_req_;

  Lifecycle lifecycle_;
};


class SyncProcessRunner {
  enum Lifecycle {
    kUninitialized = 0,
    kInitialized,
    kHandlesClosed
  };

 public:
  static void Initialize(v8::Local<v8::Object> target,
                         v8::Local<v8::Value> unused,
                         v8::Local<v8::Context> context,
                         void* priv);
  static void Spawn(const v8::FunctionCallbackInfo<v8::Value>& args);

 private:
  friend class SyncProcessStdioPipe;

  explicit SyncProcessRunner(Environment* env_);
  ~SyncProcessRunner();

  inline Environment* env() const;

  v8::MaybeLocal<v8::Object> Run(v8::Local<v8::Value> options);
  v8::Maybe<bool> TryInitializeAndRunLoop(v8::Local<v8::Value> options);
  void CloseHandlesAndDeleteLoop();

  void CloseStdioPipes();
  void CloseKillTimer();

  void Kill();
  void IncrementBufferSizeAndCheckOverflow(ssize_t length);

  void OnExit(int64_t exit_status, int term_signal);
  void OnKillTimerTimeout();

  int GetError();
  void SetError(int error);
  void SetPipeError(int pipe_error);

  v8::Local<v8::Object> BuildResultObject();
  v8::Local<v8::Array> BuildOutputArray();

  v8::Maybe<int> ParseOptions(v8::Local<v8::Value> js_value);
  int ParseStdioOptions(v8::Local<v8::Value> js_value);
  int ParseStdioOption(int child_fd, v8::Local<v8::Object> js_stdio_option);

  inline int AddStdioIgnore(uint32_t child_fd);
  inline int AddStdioPipe(uint32_t child_fd,
                          bool readable,
                          bool writable,
                          uv_buf_t input_buffer);
  inline int AddStdioInheritFD(uint32_t child_fd, int inherit_fd);

  static bool IsSet(v8::Local<v8::Value> value);
  v8::Maybe<int> CopyJsString(v8::Local<v8::Value> js_value,
                              const char** target);
  v8::Maybe<int> CopyJsStringArray(v8::Local<v8::Value> js_value,
                                   char** target);

  static void ExitCallback(uv_process_t* handle,
                           int64_t exit_status,
                           int term_signal);
  static void KillTimerCallback(uv_timer_t* handle);
  static void KillTimerCloseCallback(uv_handle_t* handle);

  double max_buffer_;
  uint64_t timeout_;
  int kill_signal_;

  uv_loop_t* uv_loop_;

  uint32_t stdio_count_;
  uv_stdio_container_t* uv_stdio_containers_;
  std::vector<std::unique_ptr<SyncProcessStdioPipe>> stdio_pipes_;
  bool stdio_pipes_initialized_;

  uv_process_options_t uv_process_options_;
  const char* file_buffer_;
  char* args_buffer_;
  char* env_buffer_;
  const char* cwd_buffer_;

  uv_process_t uv_process_;
  bool killed_;

  size_t buffered_output_size_;
  int64_t exit_status_;
  int term_signal_;

  uv_timer_t uv_timer_;
  bool kill_timer_initialized_;

  // Errors that happen in one of the pipe handlers are stored in the
  // `pipe_error` field. They are treated as "low-priority", only to be
  // reported if no more serious errors happened.
  int error_;
  int pipe_error_;

  Lifecycle lifecycle_;

  Environment* env_;
};

}  // namespace node

#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#endif  // SRC_SPAWN_SYNC_H_
