// 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,
                   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);

  // 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_ != NULL) {
      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_(NULL) {
    if (next_ != NULL) {
      next_->prev_ = this;
    }
  }

  ~SignalInfo();

  void Unlink() {
    if (prev_ != NULL) {
      prev_->next_ = next_;
    }
    if (next_ != NULL) {
      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 const 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_ = NULL;
    }

    ~BufferListNode() { delete[] data_; }

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

    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_(NULL), tail_(NULL), 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 != NULL;
         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_ == NULL) && (tail_ == NULL); }
#endif

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

  void Free() {
    BufferListNode* current = head_;
    while (current != NULL) {
      BufferListNode* tmp = current;
      current = current->next();
      delete tmp;
    }
    head_ = NULL;
    tail_ = NULL;
    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_
