// 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.

#ifndef SRC_LIB_LOADER_SERVICE_LOADER_SERVICE_H_
#define SRC_LIB_LOADER_SERVICE_LOADER_SERVICE_H_

#include <fuchsia/ldsvc/llcpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/zx/channel.h>
#include <lib/zx/status.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>

#include <memory>

#include <fbl/macros.h>
#include <fbl/unique_fd.h>

namespace loader {

// Pure virtual base class for a fuchsia.ldsvc.Loader FIDL server. See concrete LoaderService
// implementation below, which should fit most use cases, or subclass to customize the behavior of
// LoadObjectImpl for your use case.
//
// Connections to the loader service stay alive as long as the client keeps the connection open (and
// other obvious things, like the async dispatcher is not shutdown and the hosting process is
// alive), even if the creator of the service drops any copies of this object.
class LoaderServiceBase : public std::enable_shared_from_this<LoaderServiceBase> {
 public:
  virtual ~LoaderServiceBase();

  // Bind and Connect create a new connection to the loader service. Connect is identical to
  // Bind but creates the channel for the caller.
  zx::status<> Bind(zx::channel channel);
  zx::status<zx::channel> Connect();

 protected:
  LoaderServiceBase(async_dispatcher_t* dispatcher, std::string name)
      : dispatcher_(dispatcher), name_(std::move(name)) {}

 private:
  // Pure virtual methods to be implemented by subclasses.
  //
  // LoadObjectImpl shall return a VMO with the contents of the specified path. The interpretation
  // of the path is defined by the concrete subclass; it may simply open the path from a given
  // directory, or may do something more complex.
  //
  // The returned VMO shall have the ZX_RIGHT_EXECUTE right, i.e. the file must be opened executable
  // or this call shall fail with ZX_ERR_ACCESS_DENIED if the file cannot be opened executable.
  //
  // The path parameter may contain one or more path components. The base class handles applying
  // loader config as requested by the client. For example, a `Config("asan!")` call followed by a
  // `LoadObject("libfoo.so")` call will result in the base class calling this with
  // "asan/libfoo.so".
  virtual zx::status<zx::vmo> LoadObjectImpl(std::string path) = 0;

  const std::string& log_prefix();

  async_dispatcher_t* dispatcher_;
  // This name is only used when logging to provide useful context for which loader service is
  // logging, since processes which host loaders sometimes host many of them.
  std::string name_;
  std::string log_prefix_;

  friend class LoaderConnection;

  DISALLOW_COPY_ASSIGN_AND_MOVE(LoaderServiceBase);
};

// Represents a single client connection to the loader service, including per-connection state. Used
// internally by LoaderServiceBase and not intended to be used directly.
//
// Connections have a strong reference to the server object (through std::shared_ptr), which keeps
// the loader service alive as long as any open client connections exist.
class LoaderConnection : public llcpp::fuchsia::ldsvc::Loader::Interface {
 public:
  LoaderConnection(std::shared_ptr<LoaderServiceBase> server) : server_(server) {}

  // llcpp::fuchsia::ldsvc::Loader::Interface implementation
  virtual void Done(DoneCompleter::Sync& completer) override;
  virtual void LoadObject(fidl::StringView object_name,
                          LoadObjectCompleter::Sync& completer) override;
  virtual void Config(fidl::StringView config, ConfigCompleter::Sync& completer) override;
  virtual void Clone(zx::channel loader, CloneCompleter::Sync& completer) override;

 private:
  const std::string& log_prefix() { return server_->log_prefix(); }

  // Wraps loader configuration set through the fuchsia.ldsvc.Loader.Config FIDL method.
  struct LoadConfig {
    std::string subdir;
    bool exclusive;
  };

  std::shared_ptr<LoaderServiceBase> server_;
  LoadConfig config_;

  DISALLOW_COPY_ASSIGN_AND_MOVE(LoaderConnection);
};

// Concrete implementation of a fuchsia.ldsvc.Loader FIDL server that serves libraries from a single
// directory, e.g. from a component's specific "/pkg/lib/" directory.
class LoaderService : public LoaderServiceBase {
 public:
  // This takes ownership of the 'lib_dir` fd and will close it automatically once all connections
  // to the loader service are closed and copies of this object are destroyed. `name` is used to
  // provide context when logging.
  static std::shared_ptr<LoaderService> Create(async_dispatcher_t* dispatcher,
                                               fbl::unique_fd lib_dir, std::string name);

 protected:
  LoaderService(async_dispatcher_t* dispatcher, fbl::unique_fd lib_dir, std::string name)
      : LoaderServiceBase(dispatcher, std::move(name)), dir_(std::move(lib_dir)) {}
  virtual zx::status<zx::vmo> LoadObjectImpl(std::string path) override;

 private:
  fbl::unique_fd dir_;
};

}  // namespace loader

#endif  // SRC_LIB_LOADER_SERVICE_LOADER_SERVICE_H_
