// 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 <dirent.h>
#include <fcntl.h>
#include <fidl/fuchsia.boot/cpp/wire.h>
#include <fidl/fuchsia.debugdata/cpp/wire.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/io.h>
#include <lib/fidl/cpp/wire/channel.h>
#include <lib/fidl/cpp/wire/connect_service.h>
#include <lib/stdcompat/source_location.h>
#include <lib/stdcompat/span.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/vfs/cpp/service.h>
#include <lib/zx/channel.h>
#include <lib/zx/eventpair.h>
#include <lib/zx/result.h>
#include <lib/zx/time.h>
#include <unistd.h>
#include <zircon/assert.h>
#include <zircon/errors.h>
#include <zircon/fidl.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <array>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>

#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 {

zx::result<> ExportBootDebugData(vfs::PseudoDir& out_dir, fbl::unique_fd fd,
                                 std::string_view export_as) {
  // 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) {
    FX_LOGS(INFO) << 1;
    return zx::error(res);
  }
  size_t size = 0;
  if (auto res = vmo.get_prop_content_size(&size); res != ZX_OK) {
    FX_LOGS(INFO) << 2;
    return zx::error(res);
  }

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

  return zx::success();
}

template <typename HandleType>
bool IsSignalled(const HandleType& handle, zx_signals_t signal) {
  zx_signals_t actual = 0;
  auto status = handle.wait_one(signal, zx::time::infinite_past(), &actual);
  return (status == ZX_OK || status == ZX_ERR_TIMED_OUT) && (actual & signal) != 0;
}

enum class DataType {
  kDynamic,
  kStatic,
};

constexpr std::string_view DataTypeDir(DataType t) {
  switch (t) {
    case DataType::kDynamic:
      return kDynamicDir;
    case DataType::kStatic:
      return kStaticDir;
    default:
      return "Unknown DataType.";
  }
}

// Returns or creates the respective instance for a given |sink_name|.
vfs::PseudoDir& GetOrCreate(std::string_view sink_name, DataType type, SinkDirMap& sink_map) {
  auto it = sink_map.find(sink_name);

  // If it's the first time we see this sink, fill up the base hierarchy:
  //  root
  //    +    /static
  //    +    /dynamic
  if (it == sink_map.end()) {
    FX_LOGS(INFO) << "Encountered sink " << sink_name << " static and dynamic subdirs created";
    it = sink_map.insert(std::make_pair(sink_name, std::make_unique<vfs::PseudoDir>())).first;
    it->second->AddEntry(std::string(kStaticDir), std::make_unique<vfs::PseudoDir>());
    it->second->AddEntry(std::string(kDynamicDir), std::make_unique<vfs::PseudoDir>());
  }

  std::string path(DataTypeDir(type));

  auto& root_dir = *(it->second);
  vfs::Node* node = nullptr;
  // Both subdirs should always be available.
  ZX_ASSERT(root_dir.Lookup(path, &node) == ZX_OK);
  return *reinterpret_cast<vfs::PseudoDir*>(node);
}

}  // namespace

zx::result<> ExposeBootDebugdata(fbl::unique_fd& debugdata_root, SinkDirMap& sink_map) {
  // Iterate on every entry in the directory.
  static constexpr auto for_each_dentry = [](DIR* root, auto&& visitor) {
    // Borrow underlying FD for opening relative files.
    int root_fd = dirfd(root);
    while (auto* dentry = readdir(root)) {
      std::string_view dentry_name(dentry->d_name);
      if (dentry_name == "." || dentry_name == "..") {
        continue;
      }

      fbl::unique_fd entry_fd(openat(root_fd, dentry->d_name, O_RDONLY));
      if (!entry_fd) {
        FX_LOGS(INFO) << "Failed to obtain FD for " << dentry->d_name << ". " << strerror(errno);
        continue;
      }

      visitor(dentry, std::move(entry_fd));
    }
  };

  DIR* root = fdopendir(debugdata_root.get());
  if (!root) {
    FX_LOGS(INFO) << "Failed to obtain DIR entry from FD. " << strerror(errno);
    return zx::error(ZX_ERR_INVALID_ARGS);
  }
  // Taken by fdopendir.
  debugdata_root.release();

  auto for_each_debugdata = [&sink_map](std::string_view sink_name, DataType type,
                                        struct dirent* entry, fbl::unique_fd debugdata_fd) {
    auto res = ExportBootDebugData(GetOrCreate(sink_name, type, sink_map), std::move(debugdata_fd),
                                   entry->d_name);
    if (res.is_error()) {
      FX_LOGS(ERROR) << "Failed to export boot debugdata to: " << sink_name << "/"
                     << DataTypeDir(type) << "/" << entry->d_name;
      return;
    }

    FX_LOGS(INFO) << " Exported boot debugdata to " << sink_name << "/" << DataTypeDir(type) << "/"
                  << entry->d_name;
  };

  // Each sink contains at most two entries, mapped to either static or dynamic data.
  // "s" or "d", each of them a directory.
  auto for_each_sink = [&for_each_debugdata](struct dirent* entry, fbl::unique_fd sink_dir_fd) {
    std::string_view sink_name(entry->d_name);

    fbl::unique_fd static_dir_fd(openat(sink_dir_fd.get(), "s", O_DIRECTORY | O_RDONLY));
    if (static_dir_fd) {
      DIR* static_dir = fdopendir(static_dir_fd.get());
      if (static_dir) {
        static_dir_fd.release();
        for_each_dentry(static_dir, [&](auto* dentry, fbl::unique_fd debugdata_fd) {
          for_each_debugdata(sink_name, DataType::kStatic, dentry, std::move(debugdata_fd));
        });
        closedir(static_dir);
      }
    }

    fbl::unique_fd dynamic_dir_fd(openat(sink_dir_fd.get(), "d", O_DIRECTORY | O_RDONLY));
    if (dynamic_dir_fd) {
      DIR* dynamic_dir = fdopendir(dynamic_dir_fd.release());
      if (dynamic_dir) {
        dynamic_dir_fd.release();
        for_each_dentry(dynamic_dir, [&](auto* dentry, fbl::unique_fd debugdata_fd) {
          for_each_debugdata(sink_name, DataType::kDynamic, dentry, std::move(debugdata_fd));
        });
        closedir(dynamic_dir);
      }
    }
  };

  // Each entry in the root is a directory named after the sink.
  for_each_dentry(root, for_each_sink);
  closedir(root);
  return zx::success();
}

namespace {

class Server : public fidl::WireServer<fuchsia_boot::SvcStash>,
               public fidl::WireServer<fuchsia_io::Openable>,
               public fidl::WireServer<fuchsia_debugdata::Publisher> {
 public:
  explicit Server(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}

  SinkDirMap TakeSinkToDir() { return std::move(sink_to_dir_); }

 private:
  void Publish(PublishRequestView request, PublishCompleter::Sync& completer) override {
    DataType published_data_type = IsSignalled(request->vmo_token, ZX_EVENTPAIR_PEER_CLOSED)
                                       ? DataType::kStatic
                                       : DataType::kDynamic;
    auto& dir = GetOrCreate(request->data_sink.get(), published_data_type, sink_to_dir_);
    std::array<char, ZX_MAX_NAME_LEN> name_buff = {};
    auto name = std::to_string(svc_id_) + "-" + std::to_string(req_id_);
    if (zx_status_t status =
            request->data.get_property(ZX_PROP_NAME, name_buff.data(), name_buff.size());
        status == ZX_OK) {
      std::string name_prop(name_buff.data());
      if (!name_prop.empty()) {
        name += "." + name_prop;
      }
    }
    uint64_t size;
    if (zx_status_t status = request->data.get_prop_content_size(&size); status != ZX_OK) {
      FX_PLOGS(INFO, status) << "Failed to obtain vmo content size. Attempting to use vmo size.";
      if (zx_status_t status = request->data.get_size(&size); status != ZX_OK) {
        FX_PLOGS(INFO, status) << "Failed to obtain vmo size.";
        size = 0;
      }
    }
    FX_LOGS(INFO) << "Exposing " << request->data_sink.get() << "/"
                  << (published_data_type == DataType::kStatic ? "static/" : "dynamic/") << name
                  << " size: " << size << " bytes";
    dir.AddEntry(std::move(name), std::make_unique<vfs::VmoFile>(std::move(request->data), size));
    ++req_id_;
  }

  void Open(OpenRequestView request, OpenCompleter::Sync& completer) override {
    if (request->path.get() == fidl::DiscoverableProtocolName<fuchsia_debugdata::Publisher>) {
      FX_LOGS(INFO) << "Encountered open request to debugdata.Publisher";
      publisher_bindings_.AddBinding(
          dispatcher_, fidl::ServerEnd<fuchsia_debugdata::Publisher>{request->object.TakeChannel()},
          this, fidl::kIgnoreBindingClosure);
    } else {
      FX_LOGS(INFO) << "Encountered open request to unhandled path: " << request->path.get();
    }
  }

  void Store(StoreRequestView request, StoreCompleter::Sync& completer) override {
    FX_LOGS(INFO) << "Encountered stashed svc handle";
    fidl::ServerEnd<fuchsia_io::Directory>& directory = request->svc_endpoint;
    openable_bindings_.AddBinding(dispatcher_,
                                  fidl::ServerEnd<fuchsia_io::Openable>{directory.TakeChannel()},
                                  this, [](Server* impl, fidl::UnbindInfo) {
                                    impl->req_id_ = 0;
                                    impl->svc_id_++;
                                  });
  }

  async_dispatcher_t* const dispatcher_;
  SinkDirMap sink_to_dir_;

  // used for name generation.
  int svc_id_ = 0;
  int req_id_ = 0;

  fidl::ServerBindingGroup<fuchsia_io::Openable> openable_bindings_;
  fidl::ServerBindingGroup<fuchsia_debugdata::Publisher> publisher_bindings_;
};

}  // namespace

SinkDirMap ExtractDebugData(fidl::ServerEnd<fuchsia_boot::SvcStash> svc_stash) {
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  Server server(loop.dispatcher());
  fidl::BindServer(loop.dispatcher(), std::move(svc_stash), &server);
  loop.RunUntilIdle();
  return server.TakeSinkToDir();
}

}  // namespace early_boot_instrumentation
