// 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::RawChannelInterface {
 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_
