// 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(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);
};

class SignalInfo {
 public:
  SignalInfo(intptr_t fd, intptr_t signal, SignalInfo* next)
      : fd_(fd),
        signal_(signal),
        // 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_; }
  Dart_Port port() const { return port_; }
  SignalInfo* next() const { return next_; }

 private:
  intptr_t fd_;
  intptr_t signal_;
  // 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 occours 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(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA) ||                    \
    defined(HOST_OS_LINUX) || defined(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(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(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(HOST_OS_ANDROID) ...

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_PROCESS_H_
