// Copyright (c) 2013, 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.

#include "bin/dartutils.h"
#include "bin/io_buffer.h"
#include "bin/process.h"
#include "bin/socket.h"

#include "include/dart_api.h"


namespace dart {
namespace bin {

static const int kProcessIdNativeField = 0;

int Process::global_exit_code_ = 0;
dart::Mutex* Process::global_exit_code_mutex_ = new dart::Mutex();

// Extract an array of C strings from a list of Dart strings.
static char** ExtractCStringList(Dart_Handle strings,
                                 Dart_Handle status_handle,
                                 const char* error_msg,
                                 intptr_t* length) {
  static const intptr_t kMaxArgumentListLength = 1024 * 1024;
  ASSERT(Dart_IsList(strings));
  intptr_t len = 0;
  Dart_Handle result = Dart_ListLength(strings, &len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  // Protect against user-defined list implementations that can have
  // arbitrary length.
  if (len < 0 || len > kMaxArgumentListLength) {
    DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
    DartUtils::SetStringField(
        status_handle, "_errorMessage", "Max argument list length exceeded");
    return NULL;
  }
  *length = len;
  char** string_args = new char*[len];
  for (int i = 0; i < len; i++) {
    Dart_Handle arg = Dart_ListGetAt(strings, i);
    if (Dart_IsError(arg)) {
      delete[] string_args;
      Dart_PropagateError(arg);
    }
    if (!Dart_IsString(arg)) {
      DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
      DartUtils::SetStringField(
          status_handle, "_errorMessage", error_msg);
      delete[] string_args;
      return NULL;
    }
    string_args[i] = const_cast<char *>(DartUtils::GetStringValue(arg));
  }
  return string_args;
}

void FUNCTION_NAME(Process_Start)(Dart_NativeArguments args) {
  Dart_Handle process =  Dart_GetNativeArgument(args, 0);
  intptr_t process_stdin;
  intptr_t process_stdout;
  intptr_t process_stderr;
  intptr_t exit_event;
  Dart_Handle status_handle = Dart_GetNativeArgument(args, 9);
  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
  // The Dart code verifies that the path implements the String
  // interface. However, only builtin Strings are handled by
  // GetStringValue.
  if (!Dart_IsString(path_handle)) {
    DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
    DartUtils::SetStringField(
        status_handle, "_errorMessage", "Path must be a builtin string");
    Dart_SetReturnValue(args, Dart_NewBoolean(false));
    return;
  }
  const char* path = DartUtils::GetStringValue(path_handle);
  Dart_Handle arguments = Dart_GetNativeArgument(args, 2);
  intptr_t args_length = 0;
  char** string_args =
      ExtractCStringList(arguments,
                         status_handle,
                         "Arguments must be builtin strings",
                         &args_length);
  if (string_args == NULL) {
    Dart_SetReturnValue(args, Dart_NewBoolean(false));
    return;
  }
  Dart_Handle working_directory_handle = Dart_GetNativeArgument(args, 3);
  // Defaults to the current working directoy.
  const char* working_directory = NULL;
  if (Dart_IsString(working_directory_handle)) {
    working_directory = DartUtils::GetStringValue(working_directory_handle);
  } else if (!Dart_IsNull(working_directory_handle)) {
    delete[] string_args;
    DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
    DartUtils::SetStringField(
        status_handle, "_errorMessage",
        "WorkingDirectory must be a builtin string");
    Dart_SetReturnValue(args, Dart_NewBoolean(false));
    return;
  }
  Dart_Handle environment = Dart_GetNativeArgument(args, 4);
  intptr_t environment_length = 0;
  char** string_environment = NULL;
  if (!Dart_IsNull(environment)) {
    string_environment =
        ExtractCStringList(environment,
                           status_handle,
                           "Environment values must be builtin strings",
                           &environment_length);
    if (string_environment == NULL) {
      delete[] string_args;
      Dart_SetReturnValue(args, Dart_NewBoolean(false));
      return;
    }
  }
  Dart_Handle stdin_handle = Dart_GetNativeArgument(args, 5);
  Dart_Handle stdout_handle = Dart_GetNativeArgument(args, 6);
  Dart_Handle stderr_handle = Dart_GetNativeArgument(args, 7);
  Dart_Handle exit_handle = Dart_GetNativeArgument(args, 8);
  intptr_t pid = -1;
  char* os_error_message = NULL;

  int error_code = Process::Start(path,
                                  string_args,
                                  args_length,
                                  working_directory,
                                  string_environment,
                                  environment_length,
                                  &process_stdout,
                                  &process_stdin,
                                  &process_stderr,
                                  &pid,
                                  &exit_event,
                                  &os_error_message);
  if (error_code == 0) {
    Socket::SetSocketIdNativeField(stdin_handle, process_stdin);
    Socket::SetSocketIdNativeField(stdout_handle, process_stdout);
    Socket::SetSocketIdNativeField(stderr_handle, process_stderr);
    Socket::SetSocketIdNativeField(exit_handle, exit_event);
    Process::SetProcessIdNativeField(process, pid);
  } else {
    DartUtils::SetIntegerField(
        status_handle, "_errorCode", error_code);
    DartUtils::SetStringField(
        status_handle, "_errorMessage", os_error_message);
  }
  delete[] string_args;
  delete[] string_environment;
  free(os_error_message);
  Dart_SetReturnValue(args, Dart_NewBoolean(error_code == 0));
}


void FUNCTION_NAME(Process_Wait)(Dart_NativeArguments args) {
  Dart_Handle process =  Dart_GetNativeArgument(args, 0);
  Dart_Handle stdin_handle =  Dart_GetNativeArgument(args, 1);
  Dart_Handle stdout_handle =  Dart_GetNativeArgument(args, 2);
  Dart_Handle stderr_handle =  Dart_GetNativeArgument(args, 3);
  Dart_Handle exit_handle =  Dart_GetNativeArgument(args, 4);
  intptr_t process_stdin;
  intptr_t process_stdout;
  intptr_t process_stderr;
  intptr_t exit_event;
  Socket::GetSocketIdNativeField(stdin_handle, &process_stdin);
  Socket::GetSocketIdNativeField(stdout_handle, &process_stdout);
  Socket::GetSocketIdNativeField(stderr_handle, &process_stderr);
  Socket::GetSocketIdNativeField(exit_handle, &exit_event);
  ProcessResult result;
  intptr_t pid;
  Process::GetProcessIdNativeField(process, &pid);
  if (Process::Wait(pid,
                    process_stdin,
                    process_stdout,
                    process_stderr,
                    exit_event,
                    &result)) {
    Dart_Handle out = result.stdout_data();
    if (Dart_IsError(out)) Dart_PropagateError(out);
    Dart_Handle err = result.stderr_data();
    if (Dart_IsError(err)) Dart_PropagateError(err);
    Dart_Handle list = Dart_NewList(4);
    Dart_ListSetAt(list, 0, Dart_NewInteger(pid));
    Dart_ListSetAt(list, 1, Dart_NewInteger(result.exit_code()));
    Dart_ListSetAt(list, 2, out);
    Dart_ListSetAt(list, 3, err);
    Dart_SetReturnValue(args, list);
  } else {
    Dart_Handle error = DartUtils::NewDartOSError();
    Process::Kill(pid, 9);
    if (Dart_IsError(error)) Dart_PropagateError(error);
    Dart_ThrowException(error);
  }
}


void FUNCTION_NAME(Process_Kill)(Dart_NativeArguments args) {
  Dart_Handle process = Dart_GetNativeArgument(args, 1);
  intptr_t pid = -1;
  Process::GetProcessIdNativeField(process, &pid);
  int signal = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
  bool success = Process::Kill(pid, signal);
  Dart_SetReturnValue(args, Dart_NewBoolean(success));
}


void FUNCTION_NAME(Process_Exit)(Dart_NativeArguments args) {
  int64_t status = 0;
  // Ignore result if passing invalid argument and just exit 0.
  DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
  exit(static_cast<int>(status));
}


void FUNCTION_NAME(Process_SetExitCode)(Dart_NativeArguments args) {
  int64_t status = 0;
  // Ignore result if passing invalid argument and just set exit code to 0.
  DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
  Process::SetGlobalExitCode(status);
}


void FUNCTION_NAME(Process_Sleep)(Dart_NativeArguments args) {
  int64_t milliseconds = 0;
  // Ignore result if passing invalid argument and just set exit code to 0.
  DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &milliseconds);
  TimerUtils::Sleep(milliseconds);
}


void FUNCTION_NAME(Process_Pid)(Dart_NativeArguments args) {
  // Ignore result if passing invalid argument and just set exit code to 0.
  intptr_t pid = -1;
  Dart_Handle process = Dart_GetNativeArgument(args, 0);
  if (Dart_IsNull(process)) {
    pid = Process::CurrentProcessId();
  } else {
    Process::GetProcessIdNativeField(process, &pid);
  }
  Dart_SetReturnValue(args, Dart_NewInteger(pid));
}


Dart_Handle Process::GetProcessIdNativeField(Dart_Handle process,
                                             intptr_t* pid) {
  return Dart_GetNativeInstanceField(process, kProcessIdNativeField, pid);
}


Dart_Handle Process::SetProcessIdNativeField(Dart_Handle process,
                                             intptr_t pid) {
  return Dart_SetNativeInstanceField(process, kProcessIdNativeField, pid);
}


void FUNCTION_NAME(SystemEncodingToString)(Dart_NativeArguments args) {
  Dart_Handle bytes = Dart_GetNativeArgument(args, 0);
  intptr_t bytes_length = 0;
  Dart_Handle result = Dart_ListLength(bytes, &bytes_length);
  if (Dart_IsError(result)) Dart_PropagateError(result);
  uint8_t* buffer = new uint8_t[bytes_length + 1];
  result = Dart_ListGetAsBytes(bytes, 0, buffer, bytes_length);
  buffer[bytes_length] = '\0';
  if (Dart_IsError(result)) {
    delete[] buffer;
    Dart_PropagateError(result);
  }
  char* str =
      StringUtils::ConsoleStringToUtf8(reinterpret_cast<char*>(buffer));
  Dart_SetReturnValue(args, DartUtils::NewString(str));
  if (str != reinterpret_cast<char*>(buffer)) free(str);
}


void FUNCTION_NAME(StringToSystemEncoding)(Dart_NativeArguments args) {
  Dart_Handle str = Dart_GetNativeArgument(args, 0);
  const char* utf8 = DartUtils::GetStringValue(str);
  const char* system_string = StringUtils::Utf8ToConsoleString(utf8);
  int external_length = strlen(system_string);
  uint8_t* buffer = NULL;
  Dart_Handle external_array = IOBuffer::Allocate(external_length, &buffer);
  memmove(buffer, system_string, external_length);
  if (utf8 != system_string) free(const_cast<char*>(system_string));
  Dart_SetReturnValue(args, external_array);
}

}  // namespace bin
}  // namespace dart
