// Copyright (c) 2016, 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 <fcntl.h>
#include <launchpad/launchpad.h>
#include <launchpad/vmo.h>
#include <magenta/syscalls.h>
#include <mxio/util.h>
#include <pthread.h>
#include <runtime/status.h>
#include <runtime/sysinfo.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// This program runs Dart VM unit tests. The Dart VM unit tests are contained
// in a separate binary whose location is defined in kRunVmTestsPath below.
// That program accepts a command line argument --list to list all the available
// tests, or the name of a single test to run. This program grabs the list of
// tests, and then runs them.

// TODO(zra): Make this a command line argument
const char* kRunVmTestsPath = "/boot/bin/dart_vm_tests";

// Tests that are invalid, wedge, or cause panics.
const char* kSkip[] = {
  // These expect a file to exist that we aren't putting in the image.
  "Read",
  "FileLength",
  "FilePosition",
  // Crash in abort() and then hang. (MG-252)
  "ArrayLengthMaxElements",
  "Int8ListLengthMaxElements",
  "ArrayNew_Overflow_Crash",
  "SNPrint_BadArgs",
  "IsolateReload_PendingUnqualifiedCall_InstanceToStatic",
  "IsolateReload_PendingUnqualifiedCall_StaticToInstance",
  "IsolateReload_PendingConstructorCall_AbstractToConcrete",
  "IsolateReload_PendingConstructorCall_ConcreteToAbstract",
  "IsolateReload_PendingStaticCall_DefinedToNSM",
  "IsolateReload_PendingStaticCall_NSMToDefined",
  // The profiler is turned off.
  "Profiler_AllocationSampleTest",
  "Profiler_ArrayAllocation",
  "Profiler_BasicSourcePosition",
  "Profiler_BasicSourcePositionOptimized",
  "Profiler_BinaryOperatorSourcePosition",
  "Profiler_BinaryOperatorSourcePositionOptimized",
  "Profiler_ChainedSamples",
  "Profiler_ClosureAllocation",
  "Profiler_CodeTicks",
  "Profiler_ContextAllocation",
  "Profiler_FunctionInline",
  "Profiler_FunctionTicks",
  "Profiler_InliningIntervalBoundry",
  "Profiler_IntrinsicAllocation",
  "Profiler_SampleBufferIterateTest",
  "Profiler_SampleBufferWrapTest",
  "Profiler_SourcePosition",
  "Profiler_SourcePositionOptimized",
  "Profiler_StringAllocation",
  "Profiler_StringInterpolation",
  "Profiler_ToggleRecordAllocation",
  "Profiler_TrivialRecordAllocation",
  "Profiler_TypedArrayAllocation",
  "Profiler_GetSourceReport",
  "Service_Profile",
  // No realpath, files not in image.
  "Dart2JSCompilerStats",
  "Dart2JSCompileAll",
  // Uses too much memory.
  "PrintJSON",
  // Need OS::GetCurrentThreadCPUMicros.
  // Skipping because they crash and hang. (MG-252)
  "Timeline_Dart_TimelineGetTrace",
  "Timeline_Dart_TimelineGetTraceOnlyDartEvents",
  "Timeline_Dart_TimelineGetTraceWithDartEvents",
  "Timeline_Dart_TimelineGetTraceGlobalOverride",
  "Timeline_Dart_GlobalTimelineGetTrace",
  "Timeline_Dart_GlobalTimelineGetTrace_Threaded",
  "TimelineEventDuration",
  "TimelineEventDurationPrintJSON",
  "TimelineEventArguments",
  "TimelineEventArgumentsPrintJSON",
  "TimelineEventCallbackRecorderBasic",
  "TimelineAnalysis_ThreadBlockCount",
  "TimelineRingRecorderJSONOrder",
  "TimelinePauses_BeginEnd",
};

// Expected to fail/crash.
const char* kExpectFail[] = {
  "Fail0",
  "Fail1",
  "Fail2",
  "AllocGeneric_Overflow",
  "CodeImmutability",
};

// Bugs to fix, or things that are not yet implemented.
const char* kBugs[] = {
  // Needs NativeSymbolResolver
  "Service_PersistentHandles",
  // Needs lstat
  "DirectoryCreateTemp",
  "DirectoryCreateDelete",
  // Needs rename
  "DirectoryRename",
  // Needs read of RSS.
  "InitialRSS",
};


static bool contains(const char** list, intptr_t len, const char* str) {
  for (intptr_t i = 0; i < len; i++) {
    if (strcmp(list[i], str) == 0) {
      return true;
    }
  }
  return false;
}


static bool isSkip(const char* test) {
  return contains(
      kSkip, sizeof(kSkip) / sizeof(kSkip[0]), test);
}


static bool isExpectFail(const char* test) {
  return contains(
      kExpectFail, sizeof(kExpectFail) / sizeof(kExpectFail[0]), test);
}


static bool isBug(const char* test) {
  return contains(kBugs, sizeof(kBugs) / sizeof(kBugs[0]), test);
}


#define RETURN_IF_ERROR(status)                                                \
  if (status < 0) {                                                            \
    fprintf(stderr, "%s:%d: Magenta call failed: %s\n",                        \
        __FILE__, __LINE__, mx_strstatus(static_cast<mx_status_t>(status)));   \
    fflush(0);                                                                 \
    return status;                                                             \
  }                                                                            \


// This is mostly taken from //magenta/system/uapp/mxsh with the addtion of
// launchpad_add_pipe calls to setup pipes for stdout and stderr.
static mx_status_t lp_setup(launchpad_t** lp_out, mx_handle_t binary_vmo,
                            int argc, const char* const* argv,
                            int *stdout_out, int *stderr_out) {
  if ((lp_out == NULL) || (stdout_out == NULL) || (stderr_out == NULL)) {
    return ERR_INVALID_ARGS;
  }
  launchpad_t* lp;
  mx_status_t status;
  status = launchpad_create(argv[0], &lp);
  RETURN_IF_ERROR(status);
  status = launchpad_arguments(lp, argc, argv);
  RETURN_IF_ERROR(status);
  status = launchpad_clone_mxio_root(lp);
  RETURN_IF_ERROR(status);
  status = launchpad_add_pipe(lp, stdout_out, 1);
  RETURN_IF_ERROR(status);
  status = launchpad_add_pipe(lp, stderr_out, 2);
  RETURN_IF_ERROR(status);
  status = launchpad_add_vdso_vmo(lp);
  RETURN_IF_ERROR(status);
  status = launchpad_elf_load(lp, binary_vmo);
  RETURN_IF_ERROR(status);
  status = launchpad_load_vdso(lp, MX_HANDLE_INVALID);
  RETURN_IF_ERROR(status);
  *lp_out = lp;
  return status;
}


// Start the test running and return file descriptors for the stdout and stderr
// pipes.
static mx_handle_t start_test(mx_handle_t binary_vmo, const char* test_name,
                              int* stdout_out, int* stderr_out) {
  const intptr_t kArgc = 2;
  const char* argv[kArgc];

  argv[0] = kRunVmTestsPath;
  argv[1] = test_name;

  launchpad_t* lp = NULL;
  int stdout_pipe = -1;
  int stderr_pipe = -1;
  mx_status_t status = lp_setup(
      &lp, binary_vmo, kArgc, argv, &stdout_pipe, &stderr_pipe);
  if (status != NO_ERROR) {
    if (lp != NULL) {
      launchpad_destroy(lp);
    }
    if (stdout_pipe != -1) {
      close(stdout_pipe);
    }
    if (stderr_pipe != -1) {
      close(stderr_pipe);
    }
  }
  RETURN_IF_ERROR(status);

  mx_handle_t p = launchpad_start(lp);
  launchpad_destroy(lp);
  if (p < 0) {
    close(stdout_pipe);
    close(stderr_pipe);
  }
  RETURN_IF_ERROR(p);

  if (stdout_out != NULL) {
    *stdout_out = stdout_pipe;
  } else {
    close(stdout_pipe);
  }
  if (stderr_out != NULL) {
    *stderr_out = stderr_pipe;
  } else {
    close(stderr_pipe);
  }
  return p;
}


// Drain fd into a buffer pointed to by 'buffer'. Assumes that the data is a
// C string, and null-terminates it. Returns the number of bytes read.
static intptr_t drain_fd(int fd, char** buffer) {
  const intptr_t kDrainInitSize = 64;
  char* buf = reinterpret_cast<char*>(malloc(kDrainInitSize));
  intptr_t free_space = kDrainInitSize;
  intptr_t total_read = 0;
  intptr_t read_size = 0;
  while ((read_size = read(fd, buf + total_read, free_space)) != 0) {
    if (read_size == -1) {
      break;
    }
    total_read += read_size;
    free_space -= read_size;
    if (free_space <= 1) {
      // new_size = size * 1.5.
      intptr_t new_size = (total_read << 1) - (total_read >> 1);
      buf = reinterpret_cast<char*>(realloc(buf, new_size));
      free_space = new_size - total_read;
    }
  }
  buf[total_read] = '\0';
  close(fd);
  *buffer = buf;
  return total_read;
}


// Runs test 'test_name' and gives stdout and stderr for the test in
// 'test_stdout' and 'test_stderr'. Returns the exit code from the test.
static int run_test(mx_handle_t binary_vmo, const char* test_name,
                    char** test_stdout, char** test_stderr) {
  int stdout_pipe = -1;
  int stderr_pipe = -1;
  mx_handle_t p = start_test(binary_vmo, test_name, &stdout_pipe, &stderr_pipe);
  RETURN_IF_ERROR(p);

  drain_fd(stdout_pipe, test_stdout);
  drain_fd(stderr_pipe, test_stderr);

  mx_signals_state_t state;
  mx_status_t r = mx_handle_wait_one(
      p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, &state);
  RETURN_IF_ERROR(r);

  mx_info_process_t proc_info;
  mx_ssize_t info_size = mx_object_get_info(
      p, MX_INFO_PROCESS, sizeof(proc_info.rec), &proc_info, sizeof(proc_info));
  RETURN_IF_ERROR(info_size);

  r = mx_handle_close(p);
  RETURN_IF_ERROR(r);
  return proc_info.rec.return_code;
}


static void handle_result(
    intptr_t result, char* test_stdout, char* test_stderr, const char* test) {
  if (result != 0) {
    if (!isExpectFail(test) && !isBug(test)) {
      printf("**** Test %s FAILED\n\nstdout:\n%s\nstderr:\n%s\n",
          test, test_stdout, test_stderr);
    } else {
      printf("Test %s FAILED and is expected to fail\n", test);
    }
  } else {
    if (isExpectFail(test)) {
      printf("**** Test %s is expected to fail, but PASSED\n\n"
             "stdout:\n%s\nstderr:\n%s\n",
             test, test_stdout, test_stderr);
    } else if (isBug(test)) {
      printf("**** Test %s is marked as a bug, but PASSED\n", test);
    } else {
      printf("Test %s PASSED\n", test);
    }
  }
}


typedef struct {
  pthread_mutex_t* test_list_lock;
  char** test_list;
  intptr_t test_list_length;
  intptr_t* test_list_index;
  mx_handle_t binary_vmo;
} runner_args_t;


static void* test_runner_thread(void* arg) {
  runner_args_t* args = reinterpret_cast<runner_args_t*>(arg);

  pthread_mutex_lock(args->test_list_lock);
  mx_handle_t binary_vmo = args->binary_vmo;
  while (*args->test_list_index < args->test_list_length) {
    const intptr_t index = *args->test_list_index;
    *args->test_list_index = index + 1;
    pthread_mutex_unlock(args->test_list_lock);

    const char* test = args->test_list[index];
    char* test_stdout = NULL;
    char* test_stderr = NULL;
    mx_handle_t vmo_dup = mx_handle_duplicate(binary_vmo, MX_RIGHT_SAME_RIGHTS);
    int test_status = run_test(vmo_dup, test, &test_stdout, &test_stderr);
    handle_result(test_status, test_stdout, test_stderr, test);
    free(test_stdout);
    free(test_stderr);
    pthread_mutex_lock(args->test_list_lock);
  }
  pthread_mutex_unlock(args->test_list_lock);

  return NULL;
}


static void run_all_tests(runner_args_t* args) {
  const intptr_t num_cpus = sysconf(_SC_NPROCESSORS_CONF);
  pthread_t* threads =
    reinterpret_cast<pthread_t*>(malloc(num_cpus * sizeof(pthread_t)));
  for (int i = 0; i < num_cpus; i++) {
    pthread_create(&threads[i], NULL, test_runner_thread, args);
  }
  for (int i = 0; i < num_cpus; i++) {
    pthread_join(threads[i], NULL);
  }
  free(threads);
}


static bool should_run(const char* test) {
  return !(test[0] == '#') && !isSkip(test);
}


static char** parse_test_list(char* list_output, intptr_t* length) {
  const intptr_t list_output_length = strlen(list_output);
  intptr_t test_count = 0;
  for (int i = 0; i < list_output_length; i++) {
    if (list_output[i] == '\n') {
      test_count++;
    }
  }
  char** test_list;
  test_list = reinterpret_cast<char**>(malloc(test_count * sizeof(*test_list)));
  char* test = list_output;
  char* strtok_context;
  intptr_t idx = 0;
  while ((test = strtok_r(test, "\n", &strtok_context)) != NULL) {
    if (should_run(test)) {
      test_list[idx] = strdup(test);
      idx++;
    }
    test = NULL;
  }

  *length = idx;
  return test_list;
}


int main(int argc, char** argv) {
  // TODO(zra): Read test binary path from the command line.

  // Load in the binary.
  mx_handle_t binary_vmo = launchpad_vmo_from_file(kRunVmTestsPath);
  RETURN_IF_ERROR(binary_vmo);

  // Run with --list to grab the list of tests.
  char* list_stdout = NULL;
  char* list_stderr = NULL;
  mx_handle_t list_vmo = mx_handle_duplicate(binary_vmo, MX_RIGHT_SAME_RIGHTS);
  RETURN_IF_ERROR(list_vmo);
  int list_result = run_test(list_vmo, "--list", &list_stdout, &list_stderr);
  if (list_result != 0) {
    fprintf(stderr, "Failed to list tests: %s\n%s\n", list_stdout, list_stderr);
    fflush(0);
    free(list_stdout);
    free(list_stderr);
    return list_result;
  }

  // Parse the test list into an array of C strings.
  intptr_t lines_count;
  char** test_list = parse_test_list(list_stdout, &lines_count);
  free(list_stdout);
  free(list_stderr);

  fprintf(stdout, "Found %ld tests\n", lines_count);
  fflush(0);

  // Run the tests across a number of threads equal to the number of cores.
  pthread_mutex_t args_mutex;
  pthread_mutex_init(&args_mutex, NULL);
  intptr_t test_list_index = 0;
  runner_args_t args;
  args.test_list_lock = &args_mutex;
  args.test_list = test_list;
  args.test_list_length = lines_count;
  args.test_list_index = &test_list_index;
  args.binary_vmo = binary_vmo;
  run_all_tests(&args);

  // Cleanup.
  for (int i = 0; i < lines_count; i++) {
    free(test_list[i]);
  }
  free(test_list);
  pthread_mutex_destroy(&args_mutex);
  mx_status_t status = mx_handle_close(binary_vmo);
  RETURN_IF_ERROR(status);

  // Complain if we didn't try to run all of the tests.
  if (test_list_index != lines_count) {
    fprintf(stderr, "Failed to attempt all the tests!\n");
    fflush(0);
    return -1;
  }
  return 0;
}
