// Copyright 2019 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 LIB_SYS_CPP_SERVICE_DIRECTORY_H_
#define LIB_SYS_CPP_SERVICE_DIRECTORY_H_

#include <fuchsia/io/cpp/fidl.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/zx/channel.h>

#include <memory>
#include <string>
#include <utility>

namespace sys {

// A directory of services provided by another component.
//
// These services are typically received by the component through its namespace,
// specifically through the "/svc" entry.
//
// Instances of this class are thread-safe.
class ServiceDirectory final {
 public:
  // Create an directory of services backed by given |directory|.
  //
  // Requests for services are routed to entries in this directory.
  //
  // The directory is expected to implement the |fuchsia.io.Directory| protocol.
  explicit ServiceDirectory(zx::channel directory);
  explicit ServiceDirectory(fidl::InterfaceHandle<fuchsia::io::Directory> directory);

  ~ServiceDirectory();

  // ServiceDirectory objects cannot be copied.
  ServiceDirectory(const ServiceDirectory&) = delete;
  ServiceDirectory& operator=(const ServiceDirectory&) = delete;

  // ServiceDirectory objects can be moved.
  ServiceDirectory(ServiceDirectory&& other) : directory_(std::move(other.directory_)) {}
  ServiceDirectory& operator=(ServiceDirectory&& other) {
    directory_ = std::move(other.directory_);
    return *this;
  }

  // Create an directory of services from this component's namespace.
  //
  // Uses the "/svc" entry in the namespace as the backing directory for the
  // returned directory of services.
  //
  // Rather than creating a new |ServiceDirectory| consider passing |svc()| from
  // your |ComponentContext| around as that makes your code unit testable and
  // consumes one less kernel handle.
  static std::shared_ptr<ServiceDirectory> CreateFromNamespace();

  // Create a directory of services and return a request for an implementation
  // of the underlying directory in |out_request|.
  //
  // Useful when creating components.
  static std::shared_ptr<ServiceDirectory> CreateWithRequest(zx::channel* out_request);
  static std::shared_ptr<ServiceDirectory> CreateWithRequest(
      fidl::InterfaceRequest<fuchsia::io::Directory>* out_request);

  // Connect to an interface in the directory.
  //
  // The discovery name of the interface is inferred from the C++ type of the
  // interface. Callers can supply an interface name explicitly to override
  // the default name.
  //
  // This overload for |Connect| discards the status of the underlying
  // connection operation. Callers that wish to recieve that status should use
  // one of the other overloads that returns a |zx_status_t|.
  //
  // # Example
  //
  // ```
  // auto controller = directory.Connect<fuchsia::foo::Controller>();
  // ```
  template <typename Interface>
  fidl::InterfacePtr<Interface> Connect(
      const std::string& interface_name = Interface::Name_) const {
    fidl::InterfacePtr<Interface> result;
    Connect(result.NewRequest(), interface_name);
    return std::move(result);
  }

  // Connect to an interface in the directory.
  //
  // The discovery name of the interface is inferred from the C++ type of the
  // interface request. Callers can supply an interface name explicitly to
  // override the default name.
  //
  // Returns whether the request was successfully sent to the remote directory
  // backing this service bundle.
  //
  // # Errors
  //
  // ZX_ERR_UNAVAILABLE: The directory backing this service bundle is invalid.
  //
  // ZX_ERR_ACCESS_DENIED: This service bundle has insufficient rights to
  // connect to services.
  //
  // # Example
  //
  // ```
  // fuchsia::foo::ControllerPtr controller;
  // directory.Connect(controller.NewRequest());
  // ```
  template <typename Interface>
  zx_status_t Connect(fidl::InterfaceRequest<Interface> request,
                      const std::string& interface_name = Interface::Name_) const {
    return Connect(interface_name, request.TakeChannel());
  }

  // Connect to an interface in the directory.
  //
  // The interface name and the channel must be supplied explicitly.
  //
  // Returns whether the request was successfully sent to the remote directory
  // backing this service bundle.
  //
  // # Errors
  //
  // ZX_ERR_UNAVAILABLE: The directory backing this service bundle is invalid.
  //
  // ZX_ERR_ACCESS_DENIED: This service bundle has insufficient rights to
  // connect to services.
  //
  // # Example
  //
  // ```
  // zx::channel controller, request;
  // zx_status_t status = zx::channel::create(0, &controller, &request);
  // if (status != ZX_OK) {
  //   [...]
  // }
  // directory.Connect("fuchsia.foo.Controller", std::move(request));
  // ```
  zx_status_t Connect(const std::string& interface_name, zx::channel request) const;

  // Clone underlying directory channel.
  //
  // This overload for |CloneHandle| discards the status of the underlying
  // operation. Callers that wish to recieve that status should use
  // other overload that returns a |zx_status_t|.
  fidl::InterfaceHandle<fuchsia::io::Directory> CloneChannel() const;

  // Clone underlying directory channel.
  //
  // Returns whether the request was successfully sent to the remote directory
  // backing this service bundle.
  //
  // # Errors
  //
  // ZX_ERR_UNAVAILABLE: The directory backing this service bundle is invalid.
  //
  // Other transport and application-level errors associated with
  // |fuchsia.io.Node/Clone|.
  //
  // # Example
  //
  // ```
  // fuchsia::io::DirectoryPtr dir;
  // directory.CloneHandle(dir.NewRequest());
  // ```
  zx_status_t CloneChannel(fidl::InterfaceRequest<fuchsia::io::Directory>) const;

 private:
  // The directory to which connection requests are routed.
  //
  // Implements |fuchsia.io.Directory| protocol.
  zx::channel directory_;
};

}  // namespace sys

#endif  // LIB_SYS_CPP_SERVICE_DIRECTORY_H_
