// Copyright 2019 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 "garnet/testing/benchmarking/is_vulkan_supported.h"

#include <optional>
#include <string>
#include <vector>

#include <unistd.h>

#include "src/lib/fxl/logging.h"

#include <lib/fdio/spawn.h>
#include <lib/zx/handle.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>

namespace benchmarking {

bool IsVulkanSupported() {
  std::vector<std::string> command = {
      // clang-format off
      "/pkgfs/packages/run/0/bin/run",
      "fuchsia-pkg://fuchsia.com/vulkan_is_supported#meta/vulkan_is_supported.cmx",
      // clang-format on
  };

  std::vector<const char*> raw_command;
  for (const auto& arg : command) {
    raw_command.push_back(arg.c_str());
  }
  raw_command.push_back(nullptr);

  int pipefd[2];
  int pipe_status = pipe(pipefd);
  FXL_CHECK(pipe_status == 0);

  std::vector<fdio_spawn_action_t> actions = {
      {.action = FDIO_SPAWN_ACTION_CLONE_FD, .fd = {.local_fd = pipefd[1], .target_fd = 1}}};

  zx::handle subprocess;
  zx_status_t status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, raw_command[0],
                                      raw_command.data(), nullptr, actions.size(), actions.data(),
                                      subprocess.reset_and_get_address(), nullptr);
  FXL_CHECK(status == ZX_OK);

  zx_signals_t signals_observed = 0;
  status = subprocess.wait_one(ZX_TASK_TERMINATED, zx::time(ZX_TIME_INFINITE), &signals_observed);
  FXL_CHECK(status == ZX_OK);
  zx_info_process_t proc_info;
  status = subprocess.get_info(ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr);
  FXL_CHECK(status == ZX_OK);

  FXL_CHECK(proc_info.return_code == 0);
  int close_result = close(pipefd[1]);
  FXL_CHECK(close_result == 0);

  std::optional<char> first_char;
  char c;
  if (read(pipefd[0], &c, sizeof(c)) > 0) {
    first_char = c;
  }

  close_result = close(pipefd[0]);
  FXL_CHECK(close_result == 0);

  if (first_char && *first_char == '1') {
    return true;
  } else if (first_char && *first_char == '0') {
    return false;
  } else {
    FXL_LOG(ERROR) << "Failed to run `vulkan_is_supported`";
    exit(1);
  }
}

}  // namespace benchmarking
