// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_BIN_PROCESS_H_
#define RUNTIME_BIN_PROCESS_H_

#include <errno.h>

#include "bin/builtin.h"
#include "bin/io_buffer.h"
#include "bin/lockers.h"
#include "bin/namespace.h"
#include "bin/thread.h"
#include "platform/globals.h"
#if !defined(DART_HOST_OS_WINDOWS)
#include "platform/signal_blocker.h"
#endif
#include "platform/utils.h"

namespace dart {
namespace bin {

class ProcessResult {
 public:
  ProcessResult() : exit_code_(0) {}

  void set_stdout_data(Dart_Handle stdout_data) { stdout_data_ = stdout_data; }
  void set_stderr_data(Dart_Handle stderr_data) { stderr_data_ = stderr_data; }

  void set_exit_code(intptr_t exit_code) { exit_code_ = exit_code; }

  Dart_Handle stdout_data() { return stdout_data_; }
  Dart_Handle stderr_data() { return stderr_data_; }
  intptr_t exit_code() { return exit_code_; }

 private:
  Dart_Handle stdout_data_;
  Dart_Handle stderr_data_;
  intptr_t exit_code_;

  DISALLOW_ALLOCATION();
};

// To be kept in sync with ProcessSignal consts in sdk/lib/io/process.dart
// Note that this map is as on Linux.
enum ProcessSignals {
  kSighup = 1,
  kSigint = 2,
  kSigquit = 3,
  kSigill = 4,
  kSigtrap = 5,
  kSigabrt = 6,
  kSigbus = 7,
  kSigfpe = 8,
  kSigkill = 9,
  kSigusr1 = 10,
  kSigsegv = 11,
  kSigusr2 = 12,
  kSigpipe = 13,
  kSigalrm = 14,
  kSigterm = 15,
  kSigchld = 17,
  kSigcont = 18,
  kSigstop = 19,
  kSigtstp = 20,
  kSigttin = 21,
  kSigttou = 22,
  kSigurg = 23,
  kSigxcpu = 24,
  kSigxfsz = 25,
  kSigvtalrm = 26,
  kSigprof = 27,
  kSigwinch = 28,
  kSigpoll = 29,
  kSigsys = 31,
  kLastSignal = kSigsys,
};

// To be kept in sync with ProcessStartMode consts in sdk/lib/io/process.dart.
enum ProcessStartMode {
  kNormal = 0,
  kInheritStdio = 1,
  kDetached = 2,
  kDetachedWithStdio = 3,
};

class Process {
 public:
  static void Init();
  static void Cleanup();

  // Start a new process providing access to stdin, stdout, stderr and
  // process exit streams.
  static int Start(Namespace* namespc,
                   const char* path,
                   const char* arguments[],
                   intptr_t arguments_length,
                   const char* working_directory,
                   char* environment[],
                   intptr_t environment_length,
                   ProcessStartMode mode,
                   intptr_t* in,
                   intptr_t* out,
                   intptr_t* err,
                   intptr_t* id,
                   intptr_t* exit_handler,
                   char** os_error_message);

  static bool Wait(intptr_t id,
                   intptr_t in,
                   intptr_t out,
                   intptr_t err,
                   intptr_t exit_handler,
                   ProcessResult* result);

  // Exec process.
  // On systems that support 'exec' it will use it to replace
  // the current process image with the image corresponding to 'path'
  // On systems that do not support it (Windows) it will start in a
  // child process in the same group as the parent so that when the parent
  // is killed the child also dies.
  // Returns 0 if the process could be execed successfully
  // Returns -1 if the exec could not be done successfully and 'errmsg'
  // points to the error message
  static int Exec(Namespace* namespc,
                  const char* path,
                  const char* arguments[],
                  intptr_t arguments_length,
                  const char* working_directory,
                  char* errmsg,
                  intptr_t errmsg_len);

  // Kill a process with a given pid.
  static bool Kill(intptr_t id, int signal);

  // Terminate the exit code handler thread. Does not return before
  // the thread has terminated.
  static void TerminateExitCodeHandler();

  static int GlobalExitCode() {
    MutexLocker ml(global_exit_code_mutex_);
    return global_exit_code_;
  }

  static void SetGlobalExitCode(int exit_code) {
    MutexLocker ml(global_exit_code_mutex_);
    global_exit_code_ = exit_code;
  }

  typedef void (*ExitHook)(int64_t exit_code);
  static void SetExitHook(ExitHook hook) { exit_hook_ = hook; }
  static void RunExitHook(int64_t exit_code) {
    if (exit_hook_ != nullptr) {
      exit_hook_(exit_code);
    }
  }

  static intptr_t CurrentProcessId();

  static intptr_t SetSignalHandler(intptr_t signal);
  // When there is a current Isolate and the 'port' argument is
  // Dart_GetMainPortId(), this clears the signal handler for the current
  // isolate. When 'port' is ILLEGAL_PORT, this clears all signal handlers for
  // 'signal' for all Isolates.
  static void ClearSignalHandler(intptr_t signal, Dart_Port port);
  static void ClearSignalHandlerByFd(intptr_t fd, Dart_Port port);
  static void ClearAllSignalHandlers();

  static Dart_Handle GetProcessIdNativeField(Dart_Handle process,
                                             intptr_t* pid);
  static Dart_Handle SetProcessIdNativeField(Dart_Handle process, intptr_t pid);

  static int64_t CurrentRSS();
  static int64_t MaxRSS();
  static void GetRSSInformation(int64_t* max_rss, int64_t* current_rss);

  static bool ModeIsAttached(ProcessStartMode mode);
  static bool ModeHasStdio(ProcessStartMode mode);

 private:
  static int global_exit_code_;
  static Mutex* global_exit_code_mutex_;
  static ExitHook exit_hook_;

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(Process);
};

typedef void (*sa_handler_t)(int);

class SignalInfo {
 public:
  SignalInfo(intptr_t fd,
             intptr_t signal,
             sa_handler_t oldact,
             SignalInfo* next)
      : fd_(fd),
        signal_(signal),
        oldact_(oldact),
        // SignalInfo is expected to be created when in a isolate.
        port_(Dart_GetMainPortId()),
        next_(next),
        prev_(nullptr) {
    if (next_ != nullptr) {
      next_->prev_ = this;
    }
  }

  ~SignalInfo();

  void Unlink() {
    if (prev_ != nullptr) {
      prev_->next_ = next_;
    }
    if (next_ != nullptr) {
      next_->prev_ = prev_;
    }
  }

  intptr_t fd() const { return fd_; }
  intptr_t signal() const { return signal_; }
  sa_handler_t oldact() const { return oldact_; }
  Dart_Port port() const { return port_; }
  SignalInfo* next() const { return next_; }

 private:
  intptr_t fd_;
  intptr_t signal_;
  sa_handler_t oldact_;
  // The port_ is used to identify what isolate the signal-info belongs to.
  Dart_Port port_;
  SignalInfo* next_;
  SignalInfo* prev_;

  DISALLOW_COPY_AND_ASSIGN(SignalInfo);
};

// Utility class for collecting the output when running a process
// synchronously by using Process::Wait. This class is sub-classed in
// the platform specific files to implement reading into the buffers
// allocated.
class BufferListBase {
 protected:
  static constexpr intptr_t kBufferSize = 16 * 1024;

  class BufferListNode {
   public:
    explicit BufferListNode(intptr_t size) {
      data_ = new uint8_t[size];
      // We check for a failed allocation below in Allocate()
      next_ = nullptr;
    }

    ~BufferListNode() { delete[] data_; }

    bool Valid() const { return data_ != nullptr; }

    uint8_t* data() const { return data_; }
    BufferListNode* next() const { return next_; }
    void set_next(BufferListNode* n) { next_ = n; }

   private:
    uint8_t* data_;
    BufferListNode* next_;

    DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode);
  };

 public:
  BufferListBase()
      : head_(nullptr), tail_(nullptr), data_size_(0), free_size_(0) {}
  ~BufferListBase() {
    Free();
    DEBUG_ASSERT(IsEmpty());
  }

  // Returns the collected data as a Uint8List. If an error occurs an
  // error handle is returned.
  Dart_Handle GetData() {
    uint8_t* buffer;
    intptr_t buffer_position = 0;
    Dart_Handle result = IOBuffer::Allocate(data_size_, &buffer);
    if (Dart_IsNull(result)) {
      return DartUtils::NewDartOSError();
    }
    if (Dart_IsError(result)) {
      Free();
      return result;
    }
    for (BufferListNode* current = head_; current != nullptr;
         current = current->next()) {
      intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize);
      memmove(buffer + buffer_position, current->data(), to_copy);
      buffer_position += to_copy;
      data_size_ -= to_copy;
    }
    ASSERT(data_size_ == 0);
    Free();
    return result;
  }

#if defined(DEBUG)
  bool IsEmpty() const { return (head_ == nullptr) && (tail_ == nullptr); }
#endif

 protected:
  bool Allocate() {
    ASSERT(free_size_ == 0);
    BufferListNode* node = new BufferListNode(kBufferSize);
    if ((node == nullptr) || !node->Valid()) {
      // Failed to allocate a buffer for the node.
      delete node;
      return false;
    }
    if (head_ == nullptr) {
      head_ = node;
      tail_ = node;
    } else {
      ASSERT(tail_->next() == nullptr);
      tail_->set_next(node);
      tail_ = node;
    }
    free_size_ = kBufferSize;
    return true;
  }

  void Free() {
    BufferListNode* current = head_;
    while (current != nullptr) {
      BufferListNode* tmp = current;
      current = current->next();
      delete tmp;
    }
    head_ = nullptr;
    tail_ = nullptr;
    data_size_ = 0;
    free_size_ = 0;
  }

  // Returns the address of the first byte in the free space.
  uint8_t* FreeSpaceAddress() {
    return tail_->data() + (kBufferSize - free_size_);
  }

  intptr_t data_size() const { return data_size_; }
  void set_data_size(intptr_t size) { data_size_ = size; }

  intptr_t free_size() const { return free_size_; }
  void set_free_size(intptr_t size) { free_size_ = size; }

  BufferListNode* head() const { return head_; }
  BufferListNode* tail() const { return tail_; }

 private:
  // Linked list for data collected.
  BufferListNode* head_;
  BufferListNode* tail_;

  // Number of bytes of data collected in the linked list.
  intptr_t data_size_;

  // Number of free bytes in the last node in the list.
  intptr_t free_size_;

  DISALLOW_COPY_AND_ASSIGN(BufferListBase);
};

#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA) ||          \
    defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS)
class BufferList : public BufferListBase {
 public:
  BufferList() {}

  bool Read(int fd, intptr_t available) {
    // Read all available bytes.
    while (available > 0) {
      if (free_size() == 0) {
        if (!Allocate()) {
          errno = ENOMEM;
          return false;
        }
      }
      ASSERT(free_size() > 0);
      ASSERT(free_size() <= kBufferSize);
      intptr_t block_size = dart::Utils::Minimum(free_size(), available);
#if defined(DART_HOST_OS_FUCHSIA)
      intptr_t bytes = NO_RETRY_EXPECTED(
          read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
#else
      intptr_t bytes = TEMP_FAILURE_RETRY(
          read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
#endif  // defined(DART_HOST_OS_FUCHSIA)
      if (bytes < 0) {
        return false;
      }
      set_data_size(data_size() + bytes);
      set_free_size(free_size() - bytes);
      available -= bytes;
    }
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BufferList);
};
#endif  // defined(DART_HOST_OS_ANDROID) ...

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_PROCESS_H_
