// Copyright 2017 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_SVC_CPP_SERVICE_NAMESPACE_H_
#define LIB_SVC_CPP_SERVICE_NAMESPACE_H_

#include <fbl/ref_ptr.h>
#include <fs/pseudo_dir.h>
#include <fs/synchronous_vfs.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>

#include <string>
#include <unordered_map>
#include <utility>

#include <fuchsia/sys/cpp/fidl.h>
#include "lib/fidl/cpp/binding_set.h"
#include "src/lib/fxl/macros.h"

namespace component {

// ServiceNamespace lets a client to publish services in the form of a
// directory and provides compatibility with ServiceProvider.
//
// This class will be deprecated and removed once ServiceProvider is replaced
// by direct use of directories for publishing and discoverying services.
class ServiceNamespace : public fuchsia::sys::ServiceProvider {
 public:
  // |ServiceConnector| is the generic, type-unsafe interface for objects used
  // by |ServiceNamespace| to connect generic "interface requests" (i.e.,
  // just channels) specified by service name to service implementations.
  using ServiceConnector = fit::function<void(zx::channel)>;

  // Constructs this service namespace implementation in an unbound state.
  ServiceNamespace();

  // Constructs this service provider implementation, binding it to the given
  // interface request. Note: If |request| is not valid ("pending"), then the
  // object will be put into an unbound state.
  explicit ServiceNamespace(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request);

  explicit ServiceNamespace(fbl::RefPtr<fs::PseudoDir> directory);

  ~ServiceNamespace() override;

  // Gets the underlying pseudo-directory.
  const fbl::RefPtr<fs::PseudoDir>& directory() const { return directory_; }

  // Binds this service provider implementation to the given interface request.
  // Multiple bindings may be added.  They are automatically removed when closed
  // remotely.
  void AddBinding(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request);

  // Disconnect this service provider implementation and put it in a state where
  // it can be rebound to a new request (i.e., restores this object to an
  // unbound state). This may be called even if this object is already unbound.
  void Close();

  // Adds a supported service with the given |service_name|, using the given
  // |service_connector|.
  void AddServiceForName(ServiceConnector connector, const std::string& service_name);

  // Adds a supported service with the given |service_name|, using the given
  // |InterfaceRequestHandler|, which should remain valid for the lifetime of
  // this object.
  //
  // A typical usage may be:
  //
  //   service_namespace_->AddService(foobar_bindings_.GetHandler(this));
  template <typename Interface>
  void AddService(fidl::InterfaceRequestHandler<Interface> handler,
                  const std::string& service_name = Interface::Name_) {
    AddServiceForName(
        [handler = std::move(handler)](zx::channel channel) {
          handler(fidl::InterfaceRequest<Interface>(std::move(channel)));
        },
        service_name);
  }

  // Removes support for the service with the given |service_name|.
  void RemoveServiceForName(const std::string& service_name);

  // Like |RemoveServiceForName()| (above), but designed so that it can be used
  // like |RemoveService<Interface>()| or even
  // |RemoveService<Interface>(service_name)| (to parallel
  // |AddService<Interface>()|).
  template <typename Interface>
  void RemoveService(const std::string& service_name = Interface::Name_) {
    RemoveServiceForName(service_name);
  }

 private:
  // Overridden from |ServiceProvider|:
  void ConnectToService(std::string service_name, zx::channel channel) override;

  void Connect(fbl::StringPiece name, zx::channel channel);
  void ConnectCommon(const std::string& service_name, zx::channel channel);

  std::unordered_map<std::string, ServiceConnector> name_to_service_connector_;

  fbl::RefPtr<fs::PseudoDir> directory_;
  fidl::BindingSet<fuchsia::sys::ServiceProvider> bindings_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ServiceNamespace);
};

}  // namespace component

#endif  // LIB_SVC_CPP_SERVICE_NAMESPACE_H_
