// Copyright 2020 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/devices/bin/driver_host2/driver_host.h"

#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/async/cpp/task.h>
#include <lib/driver2/start_args.h>
#include <lib/fdf/cpp/dispatcher.h>
#include <lib/fdf/cpp/internal.h>
#include <lib/fdio/directory.h>
#include <lib/fit/defer.h>
#include <lib/fit/function.h>
#include <lib/sys/component/llcpp/outgoing_directory.h>
#include <zircon/dlfcn.h>

#include "src/devices/lib/log/log.h"
#include "src/lib/storage/vfs/cpp/service.h"

// The driver runtime libraries use the fdf namespace, but we would also like to use fdf
// as an alias for the fdf FIDL library.
namespace fdf {
using namespace fuchsia_driver_framework;
}  // namespace fdf

namespace fio = fuchsia_io;
namespace frunner = fuchsia_component_runner;

namespace {

class FileEventHandler : public fidl::WireAsyncEventHandler<fio::File> {
 public:
  explicit FileEventHandler(std::string url) : url_(std::move(url)) {}

  void on_fidl_error(fidl::UnbindInfo info) override {
    LOGF(ERROR, "Failed to start driver '%s', could not open library: %s", url_.data(),
         info.FormatDescription().data());
  }

 private:
  std::string url_;
};

std::string_view GetManifest(std::string_view url) {
  auto i = url.rfind('/');
  return i == std::string_view::npos ? url : url.substr(i + 1);
}

}  // namespace

zx::status<fbl::RefPtr<Driver>> Driver::Load(std::string url, zx::vmo vmo) {
  void* library = dlopen_vmo(vmo.get(), RTLD_NOW);
  if (library == nullptr) {
    LOGF(ERROR, "Failed to start driver '%s', could not load library: %s", url.data(), dlerror());
    return zx::error(ZX_ERR_INTERNAL);
  }
  auto record = static_cast<const DriverRecordV1*>(dlsym(library, "__fuchsia_driver_record__"));
  if (record == nullptr) {
    LOGF(ERROR, "Failed to start driver '%s', driver record not found", url.data());
    return zx::error(ZX_ERR_NOT_FOUND);
  }
  if (record->version != 1) {
    LOGF(ERROR, "Failed to start driver '%s', unknown driver record version: %lu", url.data(),
         record->version);
    return zx::error(ZX_ERR_WRONG_TYPE);
  }
  return zx::ok(fbl::MakeRefCounted<Driver>(std::move(url), library, record));
}

Driver::Driver(std::string url, void* library, const DriverRecordV1* record)
    : url_(std::move(url)), library_(library), record_(record) {}

Driver::~Driver() {
  if (opaque_.has_value()) {
    zx_status_t status = record_->stop(*opaque_);
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to stop driver '%s': %s", url_.data(), zx_status_get_string(status));
    }
  }
  dlclose(library_);
}

void Driver::set_binding(fidl::ServerBindingRef<fuchsia_driver_framework::Driver> binding) {
  binding_.emplace(std::move(binding));
}

void Driver::Stop(StopRequestView request, StopCompleter::Sync& completer) { binding_->Unbind(); }

zx::status<> Driver::Start(fidl::IncomingMessage& start_args,
                           fidl_opaque_wire_format_metadata_t wire_format_metadata,
                           fdf::Dispatcher dispatcher) {
  initial_dispatcher_ = std::move(dispatcher);

  // After calling |record_->start|, we assume it has taken ownership of
  // the handles from |start_args|, and can therefore relinquish ownership.
  fidl_incoming_msg_t c_msg = std::move(start_args).ReleaseToEncodedCMessage();
  void* opaque = nullptr;
  zx_status_t status =
      record_->start({&c_msg, wire_format_metadata}, initial_dispatcher_.get(), &opaque);
  if (status != ZX_OK) {
    return zx::error(status);
  }
  opaque_.emplace(opaque);
  return zx::ok();
}

DriverHost::DriverHost(inspect::Inspector& inspector, async::Loop& loop) : loop_(loop) {
  inspector.GetRoot().CreateLazyNode(
      "drivers", [this] { return Inspect(); }, &inspector);
}

fpromise::promise<inspect::Inspector> DriverHost::Inspect() {
  inspect::Inspector inspector;
  auto& root = inspector.GetRoot();
  size_t i = 0;

  std::lock_guard<std::mutex> lock(mutex_);
  for (auto& driver : drivers_) {
    auto child = root.CreateChild("driver-" + std::to_string(++i));
    child.CreateString("url", driver.url(), &inspector);
    inspector.emplace(std::move(child));
  }

  return fpromise::make_ok_promise(std::move(inspector));
}

zx::status<> DriverHost::PublishDriverHost(component::OutgoingDirectory& outgoing_directory) {
  const auto service = [this](fidl::ServerEnd<fdf::DriverHost> request) {
    fidl::BindServer(loop_.dispatcher(), std::move(request), this);
  };
  auto status = outgoing_directory.AddProtocol<fdf::DriverHost>(std::move(service));
  if (status.is_error()) {
    LOGF(ERROR, "Failed to add directory entry '%s': %s",
         fidl::DiscoverableProtocolName<fdf::DriverHost>, status.status_string());
  }

  return status;
}

uint32_t DriverHost::ExtractDefaultDispatcherOpts(const fuchsia_data::wire::Dictionary& program) {
  auto default_dispatcher_opts = driver::ProgramValueAsVector(program, "default_dispatcher_opts");

  uint32_t opts = 0;
  if (default_dispatcher_opts.is_ok()) {
    for (auto opt : *default_dispatcher_opts) {
      if (opt == "allow_sync_calls") {
        opts |= FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS;
      } else {
        LOGF(WARNING, "Ignoring unknown default_dispatcher_opt: %s", opt.c_str());
      }
    }
  }
  return opts;
}

void DriverHost::Start(StartRequestView request, StartCompleter::Sync& completer) {
  if (!request->start_args.has_url()) {
    LOGF(ERROR, "Failed to start driver, missing 'url' argument");
    completer.Close(ZX_ERR_INVALID_ARGS);
    return;
  }
  std::string url(request->start_args.url().get());
  auto pkg = request->start_args.has_ns() ? driver::NsValue(request->start_args.ns(), "/pkg")
                                          : zx::error(ZX_ERR_INVALID_ARGS);
  if (pkg.is_error()) {
    LOGF(ERROR, "Failed to start driver, missing '/pkg' directory: %s",
         zx_status_get_string(pkg.error_value()));
    completer.Close(pkg.error_value());
    return;
  }
  zx::status<std::string> binary =
      request->start_args.has_program()
          ? driver::ProgramValue(request->start_args.program(), "binary")
          : zx::error(ZX_ERR_INVALID_ARGS);
  if (binary.is_error()) {
    LOGF(ERROR, "Failed to start driver, missing 'binary' argument: %s",
         zx_status_get_string(binary.error_value()));
    completer.Close(binary.error_value());
    return;
  }
  // Open the driver's binary within the driver's package.
  auto endpoints = fidl::CreateEndpoints<fio::File>();
  if (endpoints.is_error()) {
    completer.Close(endpoints.error_value());
    return;
  }
  zx_status_t status = fdio_open_at(pkg->channel()->get(), binary->data(),
                                    static_cast<uint32_t>(fio::wire::OpenFlags::kRightReadable |
                                                          fio::wire::OpenFlags::kRightExecutable),
                                    endpoints->server.TakeChannel().release());
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to start driver '%s', could not open library: %s", url.data(),
         zx_status_get_string(status));
    completer.Close(status);
    return;
  }
  // We encode start_args outside of callback in order to access stack-allocated
  // data before it is destroyed.
  // TODO(fxbug.dev/45252): Use FIDL at rest.
  fidl::unstable::OwnedEncodedMessage<fdf::wire::DriverStartArgs> message(
      fidl::internal::WireFormatVersion::kV2, &request->start_args);
  if (!message.ok()) {
    LOGF(ERROR, "Failed to start driver '%s', could not encode start args: %s", url.data(),
         message.FormatDescription().data());
    completer.Close(message.status());
    return;
  }
  fidl_opaque_wire_format_metadata_t wire_format_metadata =
      message.wire_format_metadata().ToOpaque();

  // We convert the outgoing message into an incoming message to provide to the
  // driver on start.
  auto converted_message =
      std::make_unique<fidl::OutgoingToIncomingMessage>(message.GetOutgoingMessage());
  if (!converted_message->ok()) {
    LOGF(ERROR, "Failed to start driver '%s', could not convert start args: %s", url.data(),
         converted_message->FormatDescription().data());
    completer.Close(converted_message->status());
    return;
  }

  uint32_t default_dispatcher_opts = ExtractDefaultDispatcherOpts(request->start_args.program());

  // Once we receive the VMO from the call to GetBuffer, we can load the driver
  // into this driver host. We move the storage and encoded for start_args into
  // this callback to extend its lifetime.
  fidl::WireSharedClient file(std::move(endpoints->client), loop_.dispatcher(),
                              std::make_unique<FileEventHandler>(url));
  auto callback = [this, request = std::move(request->driver), completer = completer.ToAsync(),
                   url = std::move(url), converted_message = std::move(converted_message),
                   wire_format_metadata,
                   default_dispatcher_opts = std::move(default_dispatcher_opts), _ = file.Clone()](
                      fidl::WireUnownedResult<fio::File::GetBackingMemory>& result) mutable {
    if (!result.ok()) {
      LOGF(ERROR, "Failed to start driver '%s', could not get library VMO: %s", url.data(),
           result.error().FormatDescription().c_str());
      completer.Close(result.status());
      return;
    }
    auto& response = result.value();
    switch (response.result.Which()) {
      case fio::wire::File2GetBackingMemoryResult::Tag::kErr:
        LOGF(ERROR, "Failed to start driver '%s', could not get library VMO: %s", url.data(),
             zx_status_get_string(response.result.err()));
        completer.Close(response.result.err());
        return;
      case fio::wire::File2GetBackingMemoryResult::Tag::kResponse:
        break;
    }
    zx::vmo& vmo = response.result.response().vmo;
    // Give the driver's VMO a name. We can't fit the entire URL in the name, so
    // use the name of the manifest from the URL.
    auto manifest = GetManifest(url);
    zx_status_t status = vmo.set_property(ZX_PROP_NAME, manifest.data(), manifest.size());
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to start driver '%s', could not name library VMO: %s", url.data(),
           zx_status_get_string(status));
      completer.Close(status);
      return;
    }
    auto driver = Driver::Load(url, std::move(vmo));
    if (driver.is_error()) {
      completer.Close(driver.error_value());
      return;
    }

    fdf::Dispatcher driver_dispatcher;
    {
      // Let the driver runtime know which driver this dispatcher is for.
      // Since we haven't entered the driver yet, the runtime cannot detect
      // which driver this dispatcher is associated with.
      fdf_internal_push_driver((*driver).get());
      auto pop_driver = fit::defer([]() { fdf_internal_pop_driver(); });

      // The dispatcher must be shutdown before the dispatcher is destroyed.
      // Usually we will wait for the callback from |fdf_internal::DriverShutdown| before destroying
      // the driver object (and hence the dispatcher).
      // In the case where we fail to start the driver, the driver object would be destructed
      // immediately, so here we hold an extra reference to the driver object to ensure the
      // dispatcher will not be destructed until shutdown completes.
      //
      // We do not destroy the dispatcher in the shutdown callback, to prevent crashes that
      // would happen if the driver attempts to access the dispatcher in its Stop hook.
      uint32_t options = default_dispatcher_opts;

      // TODO(fxbug.dev/99310): When we can parse CMLs to get this information,
      // please delete these.
      if (url == "fuchsia-boot:///#meta/intel-i2c-dfv2.cm") {
        options |= FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS;
      }
      if (url == "fuchsia-boot:///#meta/i2c.cm") {
        options |= FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS;
      }
      if (url == "fuchsia-boot:///#meta/i2c-hid-dfv2.cm") {
        options |= FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS;
      }
      auto dispatcher =
          fdf::Dispatcher::Create(options, [driver_ref = *driver](fdf_dispatcher_t* dispatcher) {});
      if (dispatcher.is_error()) {
        completer.Close(dispatcher.status_value());
        return;
      }
      driver_dispatcher = *std::move(dispatcher);
    }
    async_dispatcher_t* driver_async_dispatcher = driver_dispatcher.async_dispatcher();

    // Task to start the driver. Post this to the driver dispatcher thread.
    auto start_task = [this, request = std::move(request), completer = std::move(completer),
                       converted_message = std::move(converted_message), wire_format_metadata,
                       driver = std::move(*driver),
                       driver_dispatcher = std::move(driver_dispatcher)]() mutable {
      // We have to add the driver to this list before calling Start in order to have an accurate
      // count of how many drivers exist in this driver host.
      {
        std::lock_guard<std::mutex> lock(mutex_);
        drivers_.push_back(driver);
      }
      auto remove_driver = fit::defer([this, driver = driver.get()]() {
        std::lock_guard<std::mutex> lock(mutex_);
        drivers_.erase(*driver);
      });

      // Save a ptr to the dispatcher so we can shut it down if starting the driver fails.
      fdf::UnownedDispatcher unowned_dispatcher = driver_dispatcher.borrow();
      auto start = driver->Start(converted_message->incoming_message(), wire_format_metadata,
                                 std::move(driver_dispatcher));
      if (start.is_error()) {
        LOGF(ERROR, "Failed to start driver '%s': %s", driver->url().data(), start.status_string());
        completer.Close(start.error_value());
        // If we fail to start the driver, we need to initiate shutting down the dispatcher.
        unowned_dispatcher->ShutdownAsync();
        // The dispatcher will be destroyed in the shutdown callback, when the last driver reference
        // is released.
        return;
      }
      LOGF(INFO, "Started '%s'", driver->url().data());

      auto unbind_callback = [this](Driver* driver, fidl::UnbindInfo info,
                                    fidl::ServerEnd<fuchsia_driver_framework::Driver> server) {
        if (!info.is_user_initiated()) {
          LOGF(WARNING, "Unexpected stop of driver '%s': %s", driver->url().data(),
               info.FormatDescription().data());
        }

        // Request the driver runtime shutdown all dispatchers owned by the driver.
        // Once we get the callback, we will stop the driver.
        auto driver_shutdown = std::make_unique<fdf_internal::DriverShutdown>();
        auto driver_shutdown_ptr = driver_shutdown.get();
        auto shutdown_callback = [this, driver_shutdown = std::move(driver_shutdown), driver,
                                  server = std::move(server)](const void* shutdown_driver) mutable {
          ZX_ASSERT(driver == shutdown_driver);

          std::lock_guard<std::mutex> lock(mutex_);
          // This removes the driver's unique_ptr from the list, which will
          // run the destructor and call the driver's Stop hook.
          drivers_.erase(*driver);

          // Send the epitath to the driver runner letting it know we stopped
          // the driver correctly.
          server.Close(ZX_OK);

          // If this is the last driver, shutdown the driver host.
          if (drivers_.is_empty()) {
            loop_.Quit();
          }
        };
        // We always expect this call to succeed, as we should be the only entity
        // that attempts to forcibly shutdown drivers.
        ZX_ASSERT(ZX_OK == driver_shutdown_ptr->Begin(driver, std::move(shutdown_callback)));
      };
      auto bind = fidl::BindServer(loop_.dispatcher(), std::move(request), driver.get(),
                                   std::move(unbind_callback));
      driver->set_binding(std::move(bind));
      remove_driver.cancel();
    };
    async::PostTask(driver_async_dispatcher, std::move(start_task));
  };
  file->GetBackingMemory(fio::wire::VmoFlags::kRead | fio::wire::VmoFlags::kExecute |
                         fio::wire::VmoFlags::kPrivateClone)
      .ThenExactlyOnce(std::move(callback));
}

void DriverHost::GetProcessKoid(GetProcessKoidRequestView request,
                                GetProcessKoidCompleter::Sync& completer) {
  zx_info_handle_basic_t info;
  zx_status_t status =
      zx::process::self()->get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to get info about process handle: %s", zx_status_get_string(status));
    completer.ReplyError(status);
  }
  completer.ReplySuccess(info.koid);
}
