// 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 SRC_STORAGE_LIB_VFS_CPP_SERVICE_H_
#define SRC_STORAGE_LIB_VFS_CPP_SERVICE_H_

#include <lib/fit/function.h>
#include <lib/fit/traits.h>
#include <lib/zx/channel.h>

#include <type_traits>

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

#include "vnode.h"

namespace fs {

// A node which binds a channel to a service implementation when opened.
//
// This class is thread-safe.
class Service : public Vnode {
 public:
  // Construct with fbl::MakeRefCounted.

  // Handler called to bind the provided channel to an implementation of the service.
  using Connector = fit::function<zx_status_t(zx::channel channel)>;

 private:
  // Determines if |T| has a nested type |T::ProtocolType|.
  template <typename, typename = void>
  struct has_protocol_type : public std::false_type {};
  template <typename T>
  struct has_protocol_type<T, std::void_t<typename T::ProtocolType>> : public std::true_type{};
  template <typename T>
  static constexpr inline auto has_protocol_type_v = has_protocol_type<T>::value;

  template <typename T>
  using remove_cvref_t = typename std::remove_reference<typename std::remove_cv<T>::type>::type;

  // Returns if |T| could potentially be a protocol connector:
  // - It is not |Service|.
  // - It cannot be converted to the untyped connector.
  template <typename T>
  static constexpr inline auto maybe_protocol_connector =
      std::conjunction_v<std::negation<std::is_same<remove_cvref_t<T>, Service>>,
                         std::negation<std::is_convertible<T, Connector>>>;

 public:
  // Handler called to bind the provided channel to an implementation of the service. This version
  // is typed to the exact FIDL protocol the handler will support.
  template <typename Protocol>
  using ProtocolConnector = fit::function<zx_status_t(fidl::ServerEnd<Protocol>)>;

  // |Vnode| implementation:
  fuchsia_io::NodeProtocolKinds GetProtocols() const final;
  zx::result<fs::VnodeAttributes> GetAttributes() const final;
  zx_status_t ConnectService(zx::channel channel) final;

 protected:
  friend fbl::internal::MakeRefCountedHelper<Service>;
  friend fbl::RefPtr<Service>;

  // Creates a service with the specified connector.
  //
  // If the |connector| is null, then incoming connection requests will be dropped.
  explicit Service(Connector connector);

  // Creates a service with the specified connector. This version is typed to the exact FIDL
  // protocol the handler will support:
  //
  //     auto service = fbl::MakeRefCounted<fs::Service>(
  //         [](fidl::ServerEnd<fidl_library::SomeProtocol> server_end) {
  //             // |server_end| speaks the |fidl_library::SomeProtocol| protocol.
  //             // Handle FIDL messages on |server_end|.
  //         });
  //
  // If the |connector| is null, then incoming connection requests will be dropped.
  //
  // The connector should be a callable taking a single |fidl::ServerEnd<ProtocolType>| as argument,
  // and return a |zx_status_t|.
  template <typename Callable, std::enable_if_t<maybe_protocol_connector<Callable>, bool> = true>
  explicit Service(Callable&& connector)
      : Service([connector = std::forward<Callable>(connector)](zx::channel channel) mutable {
          static_assert(
              std::is_same_v<typename fit::callable_traits<remove_cvref_t<Callable>>::return_type,
                             zx_status_t>,
              "The protocol connector should return |zx_status_t|.");
          static_assert(fit::callable_traits<remove_cvref_t<Callable>>::args::size == 1,
                        "The protocol connector should take exactly one argument.");
          using FirstArg =
              typename fit::callable_traits<remove_cvref_t<Callable>>::args::template at<0>;
          static_assert(
              has_protocol_type_v<FirstArg>,
              "The first argument of the protocol connector should be |fidl::ServerEnd<T>|.");

          using Protocol = typename FirstArg::ProtocolType;
          return connector(fidl::ServerEnd<Protocol>(std::move(channel)));
        }) {}

  // Destroys the services and releases its connector.
  ~Service() override;

 private:
  Connector connector_;

  DISALLOW_COPY_ASSIGN_AND_MOVE(Service);
};

}  // namespace fs

#endif  // SRC_STORAGE_LIB_VFS_CPP_SERVICE_H_
