// 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 <launchpad/launchpad.h>
#include <magenta/syscalls.h>
#include <magenta/syscalls/object.h>
#include <sys/stat.h>
#include <unistd.h>

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(), 0600), 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);

  CHECK_EQ(CopyFile(run_dir_name + "/" + benchmark_name, benchmark_name), 0)
      << "Error copying binary, Error: " << 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) {
  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;
}

// TODO: This is for fuchsia, need to write linux specific
#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
