// 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 <fuchsia/io/llcpp/fidl.h>
#include <lib/async-loop/loop.h>
#include <lib/fdio/directory.h>
#include <lib/fit/function.h>
#include <zircon/dlfcn.h>

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

namespace fdf = fuchsia_driver_framework;
namespace fio = fuchsia_io;
namespace frunner = fuchsia_component_runner;

namespace {

class FileEventHandler : public fidl::WireAsyncEventHandler<fio::File> {
 public:
  explicit FileEventHandler(const std::string& binary_value) : binary_value_(binary_value) {}

  void Unbound(fidl::UnbindInfo info) override {
    if (info.status != ZX_OK) {
      LOGF(ERROR, "Failed to start driver '/pkg/%s', could not open library: %s",
           binary_value_.c_str(), zx_status_get_string(info.status));
    }
  }

 private:
  const std::string& binary_value_;
};

}  // namespace

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

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

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

  if (binding_.has_value()) {
    binding_->Unbind();
  }
}

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

zx::status<> Driver::Start(fidl::OutgoingMessage& start_args, async_dispatcher_t* dispatcher) {
  auto converted = fidl::OutgoingToIncomingMessage(start_args);
  if (converted.status() != ZX_OK) {
    return zx::error(converted.status());
  }
  zx_status_t status = record_->start(converted.incoming_message(), dispatcher, &opaque_);
  // After calling |record_->start|, we assume it has taken ownership of
  // the handles from |start_args|, and can therefore relinquish ownership.
  converted.ReleaseHandles();
  return zx::make_status(status);
}

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

fit::promise<inspect::Inspector> DriverHost::Inspect() {
  inspect::Inspector inspector;
  auto& root = inspector.GetRoot();
  size_t i = 0;
  for (auto& driver : drivers_) {
    auto child = root.CreateChild("driver-" + std::to_string(++i));
    child.CreateString("url", driver.url(), &inspector);
    child.CreateString("binary", driver.binary(), &inspector);
    inspector.emplace(std::move(child));
  }
  return fit::make_ok_promise(std::move(inspector));
}

zx::status<> DriverHost::PublishDriverHost(const fbl::RefPtr<fs::PseudoDir>& svc_dir) {
  const auto service = [this](zx::channel request) {
    fidl::BindServer(loop_->dispatcher(), std::move(request), this);
    return ZX_OK;
  };
  zx_status_t status = svc_dir->AddEntry(fidl::DiscoverableProtocolName<fdf::DriverHost>,
                                         fbl::MakeRefCounted<fs::Service>(service));
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to add directory entry '%s': %s",
         fidl::DiscoverableProtocolName<fdf::DriverHost>, zx_status_get_string(status));
  }
  return zx::make_status(status);
}

void DriverHost::Start(fdf::wire::DriverStartArgs start_args,
                       fidl::ServerEnd<fuchsia_driver_framework::Driver> request,
                       StartCompleter::Sync& completer) {
  if (!start_args.has_url()) {
    LOGF(ERROR, "Failed to start driver, missing 'url' argument");
    completer.Close(ZX_ERR_INVALID_ARGS);
    return;
  }
  std::string url(start_args.url().get());
  auto pkg = start_args.has_ns() ? start_args::NsValue(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 = start_args.has_program()
                                       ? start_args::ProgramValue(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.status_value());
    return;
  }
  zx_status_t status =
      fdio_open_at(pkg->handle(), binary->data(),
                   fio::wire::OPEN_RIGHT_READABLE | fio::wire::OPEN_RIGHT_EXECUTABLE,
                   endpoints->server.TakeChannel().release());
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to start driver '/pkg/%s', could not open library: %s", binary->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.
  auto message = std::make_unique<fdf::wire::DriverStartArgs::OwnedEncodedMessage>(&start_args);
  if (!message->ok()) {
    LOGF(ERROR, "Failed to start driver '/pkg/%s', could not encode start args: %s", binary->data(),
         message->error());
    completer.Close(message->status());
    return;
  }

  // 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::Client<fio::File> file(std::move(endpoints->client), loop_->dispatcher(),
                               std::make_shared<FileEventHandler>(binary.value()));
  auto callback = [this, request = std::move(request), completer = completer.ToAsync(),
                   url = std::move(url), binary = std::move(binary.value()),
                   message = std::move(message),
                   _ = file.Clone()](fidl::WireResponse<fio::File::GetBuffer>* response) mutable {
    if (response->s != ZX_OK) {
      LOGF(ERROR, "Failed to start driver '/pkg/%s', could not get library VMO: %s", binary.data(),
           zx_status_get_string(response->s));
      completer.Close(response->s);
      return;
    }
    zx_status_t status =
        response->buffer->vmo.set_property(ZX_PROP_NAME, binary.data(), binary.size());
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to start driver '/pkg/%s', could not name library VMO: %s", binary.data(),
           zx_status_get_string(status));
      completer.Close(status);
      return;
    }
    auto driver = Driver::Load(std::move(url), binary, std::move(response->buffer->vmo));
    if (driver.is_error()) {
      completer.Close(driver.error_value());
      return;
    }
    auto driver_ptr = driver.value().get();
    auto bind = fidl::BindServer<Driver>(loop_->dispatcher(), std::move(request), driver_ptr,
                                         [this](Driver* driver, auto, auto) {
                                           drivers_.erase(*driver);
                                           // If this is the last driver, shutdown the driver host.
                                           if (drivers_.is_empty()) {
                                             loop_->Quit();
                                           }
                                         });
    driver->set_binding(std::move(bind));
    drivers_.push_back(std::move(driver.value()));

    auto start = driver_ptr->Start(message->GetOutgoingMessage(), loop_->dispatcher());
    if (start.is_error()) {
      LOGF(ERROR, "Failed to start driver '/pkg/%s': %s", binary.data(), start.status_string());
      completer.Close(start.error_value());
      return;
    }
    LOGF(INFO, "Started '%s'", binary.data());
  };
  file->GetBuffer(fio::wire::VMO_FLAG_READ | fio::wire::VMO_FLAG_EXEC | fio::wire::VMO_FLAG_PRIVATE,
                  std::move(callback));
}
