// Copyright 2022 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 "src/sys/early_boot_instrumentation/coverage_source.h"

#include <fcntl.h>
#include <lib/fdio/io.h>
#include <lib/stdcompat/span.h>
#include <lib/zx/status.h>
#include <unistd.h>

#include <string>
#include <string_view>

#include <fbl/unique_fd.h>
#include <sdk/lib/vfs/cpp/pseudo_dir.h>
#include <sdk/lib/vfs/cpp/vmo_file.h>

namespace early_boot_instrumentation {
namespace {

constexpr std::string_view kKernelProfRaw = "zircon.elf.profraw";
constexpr std::string_view kKernelSymbolizerLog = "symbolizer.log";

constexpr std::string_view kPhysbootProfRaw = "physboot.profraw";
constexpr std::string_view kPhysbootSymbolizerLog = "symbolizer.log";

struct ExportedFd {
  fbl::unique_fd fd;
  std::string export_name;
};

zx::status<> Export(vfs::PseudoDir& out_dir, cpp20::span<ExportedFd> exported_fds) {
  for (const auto& [fd, export_as] : exported_fds) {
    // Get the underlying vmo of the fd.
    zx::vmo vmo;
    if (auto res = fdio_get_vmo_exact(fd.get(), vmo.reset_and_get_address()); res != ZX_OK) {
      return zx::error(res);
    }
    size_t size = 0;
    if (auto res = vmo.get_size(&size); res != ZX_OK) {
      return zx::error(res);
    }

    auto file = std::make_unique<vfs::VmoFile>(std::move(vmo), 0, size);
    if (auto res = out_dir.AddEntry(export_as, std::move(file)); res != ZX_OK) {
      return zx::error(res);
    }
  }
  return zx::success();
}

}  // namespace

zx::status<> ExposeKernelProfileData(fbl::unique_fd& kernel_data_dir, vfs::PseudoDir& out_dir) {
  std::vector<ExportedFd> exported_fds;

  fbl::unique_fd kernel_profile(openat(kernel_data_dir.get(), kKernelProfRaw.data(), O_RDONLY));
  if (!kernel_profile) {
    return zx::error(ZX_ERR_NOT_FOUND);
  }

  exported_fds.emplace_back(
      ExportedFd{.fd = std::move(kernel_profile), .export_name = std::string(kKernelFile)});

  fbl::unique_fd kernel_log(openat(kernel_data_dir.get(), kKernelSymbolizerLog.data(), O_RDONLY));
  if (kernel_log) {
    exported_fds.emplace_back(
        ExportedFd{.fd = std::move(kernel_log), .export_name = std::string(kKernelSymbolizerFile)});
  }

  return Export(out_dir, exported_fds);
}

zx::status<> ExposePhysbootProfileData(fbl::unique_fd& physboot_data_dir, vfs::PseudoDir& out_dir) {
  std::vector<ExportedFd> exported_fds;

  fbl::unique_fd phys_profile(openat(physboot_data_dir.get(), kPhysbootProfRaw.data(), O_RDONLY));
  if (!phys_profile) {
    return zx::error(ZX_ERR_NOT_FOUND);
  }

  exported_fds.emplace_back(
      ExportedFd{.fd = std::move(phys_profile), .export_name = std::string(kPhysFile)});

  fbl::unique_fd phys_log(openat(physboot_data_dir.get(), kPhysbootSymbolizerLog.data(), O_RDONLY));
  if (phys_log) {
    exported_fds.emplace_back(
        ExportedFd{.fd = std::move(phys_log), .export_name = std::string(kPhysSymbolizerFile)});
  }

  return Export(out_dir, exported_fds);
}

}  // namespace early_boot_instrumentation
