// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "spec_fixture.h"
#include "spec_utils.h"

#include <benchmark/benchmark.h>
#include <fcntl.h>
#include <fstream>
#include <glog/logging.h>
#include <sys/stat.h>
#include <unistd.h>

#ifdef __unix__
#include <spawn.h>
#include <sys/wait.h>
#endif

#ifdef __Fuchsia__
#include <launchpad/launchpad.h>
#include <magenta/syscalls.h>
#include <magenta/syscalls/object.h>
#endif

extern std::string executableDir;
extern std::string tmpDir;
extern std::ofstream result;

namespace {
class ScopedGuard {
 public:
  explicit ScopedGuard(std::function<void()> f) : f_(f) {}
  ~ScopedGuard() noexcept { f_(); }
  ScopedGuard(const ScopedGuard&) = delete;
  ScopedGuard(ScopedGuard&&) = delete;
  ScopedGuard& operator=(const ScopedGuard&) = delete;
  ScopedGuard& operator=(ScopedGuard&&) = delete;

 private:
  std::function<void()> f_;
};
}  // namespace

void SpecFixture::SetUp(benchmark::State& st) {
  DLOG(INFO) << "Preparing benchmark: " << benchmark_name;
  run_dir_name = tmpDir + "/" + benchmark_name;

  DLOG(INFO) << "Changing dir to: " << executableDir.c_str();
  CHECK_EQ(chdir(executableDir.c_str()), 0) << "Not able to change dir to "
                                            << executableDir;
  CHECK_EQ(mkdir(run_dir_name.c_str(), 0700), 0)
      << "Not able to create dir: " << run_dir_name
      << ", Error: " << strerror(errno);

  CHECK_EQ(CopyDir(run_dir_name, "data/" + benchmark_name), 0)
      << "Error copying dir: " << run_dir_name
      << ", Error: " << strerror(errno);

  std::string binary = run_dir_name + "/" + benchmark_name;
  CHECK_EQ(CopyFile(binary, benchmark_name), 0)
      << "Error copying binary, Error: " << strerror(errno);

  CHECK_EQ(chmod(binary.c_str(), 0700), 0)
      << "Error changing file permission for binary: " << strerror(errno);
}

void SpecFixture::TearDown(benchmark::State& st) {
  CHECK_EQ(DeleteDir(run_dir_name), 0) << "Error Deleting directory "
                                       << run_dir_name
                                       << ", Error: " << strerror(errno);
}

int SpecFixture::RunSpec(const char* args[], int args_length) {
  int page_size = getpagesize();
  char** argv = new char*[args_length + 1];
  argv[0] = (char*)(benchmark_name.c_str());
  if (args_length > 0) {
    memcpy(argv + 1, args, args_length * sizeof(char*));
  }

  if (chdir(run_dir_name.c_str()) != 0) {
    LOG(ERROR) << "Not able to change dir to " << run_dir_name
               << ", Error: " << strerror(errno);
    return errno;
  }

  DLOG(INFO) << "Running benchmark";

  // Capture output
  char buffer[page_size];
  int out_p[2];
  int old_stdout = dup(STDOUT_FILENO);
  if (pipe2(out_p, O_NONBLOCK) != 0) {
    LOG(ERROR) << "Not able create pipe, Error: " << strerror(errno);
    return errno;
  }
  ScopedGuard guard([&]() { close(out_p[0]); });
  dup2(out_p[1], STDOUT_FILENO);
  close(out_p[1]);

  int status = LaunchProcess(argv, args_length + 1);

  fflush(stdout);
  dup2(old_stdout, STDOUT_FILENO);
  if (chdir(executableDir.c_str()) != 0) {
    LOG(ERROR) << "Not able to change dir to " << executableDir
               << ", Error: " << strerror(errno);
    return errno;
  }
  delete[] argv;
  if (status != 0) {
    // Dump output
    LOG(ERROR) << "Error while running benchmark";
    ssize_t len;
    do {
      len = read(out_p[0], buffer, page_size);
      if (len == -1) {
        LOG(ERROR) << "Error reading from pipe, Error: " << strerror(errno);
        return errno;
      }
      fwrite(buffer, sizeof(char), len, stderr);
    } while (len == page_size);
    fprintf(stderr, "\n");
    return 1;
  }
  return 0;
}

#ifdef __Fuchsia__
int SpecFixture::LaunchProcess(char** args, int args_length) {
  mx_handle_t handle = launchpad_launch_mxio(args[0], args_length, args);
  if (handle < 0) {
    LOG(ERROR) << "Failed to launch " << args[0] << ":" << handle;
    return handle;
  }
  mx_status_t status =
      mx_handle_wait_one(handle, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, NULL);

  if (status != NO_ERROR) {
    LOG(ERROR) << "Failed to wait for process exiting " << args[0] << ":"
               << status;
    return status;
  }

  mx_info_process_t proc_info;
  ssize_t info_status = mx_object_get_info(handle, MX_INFO_PROCESS, &proc_info,
                                           sizeof(proc_info), NULL, NULL);
  mx_handle_close(handle);

  if (info_status < 0) {
    LOG(ERROR) << "Failed to get process return code " << args[0] << ":"
               << info_status;
    return 1;
  }
  return proc_info.return_code;
}
#endif

#ifdef __unix__
int SpecFixture::LaunchProcess(char** args, int args_length) {
  run_dir_name = tmpDir + "/" + benchmark_name + "/";
  std::string command = run_dir_name + args[0];
  char** argv = new char*[args_length + 1];
  ScopedGuard guard([&]() { delete[] argv; });
  for (int i = 0; i < args_length; i++) {
    argv[i] = args[i];
  }
  argv[args_length] = NULL;
  pid_t pid;
  int status = posix_spawn(&pid, command.c_str(), NULL, NULL, argv, environ);
  if (status == 0) {
    if (waitpid(pid, &status, 0) != -1) {
      return status;
    } else {
      LOG(ERROR) << "waitpid error: " << strerror(errno);
    }
  } else {
    LOG(ERROR) << "posix_spawn error: " << strerror(status);
  }
  return -1;
}
#endif
