// 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_COMPONENT_CONTEXT_H_
#define LIB_SYS_CPP_COMPONENT_CONTEXT_H_

#include <lib/sys/cpp/outgoing_directory.h>
#include <lib/sys/cpp/service_directory.h>

#include <memory>

namespace sys {

// Context information that this component received at startup.
//
// Upon creation, components are given a namespace, which is file system local
// to the component. A components namespace lets the component interact with
// other components and the system at large. One important part of this
// namespace is the directory of services, typically located at "/svc" in the
// components namespace. The |ComponentContext| provides an ergonomic interface
// to this service bundle through its |svc()| property.
//
// In addition to receiving services, components can also publish services and
// data to other components through their outgoing namespace, which is also a
// directory. The |ComponentContext| provides an ergonomic interface for
// exposing services and other file system objects through its |outgoing()|
// property.
//
// This class is thread-hostile.
//
//  # Simple usage
//
// Instances of this class should be owned and managed on the same thread.
//
// # Advanced usage
//
// You can use a background thread to service this class provided:
// async_dispatcher_t for the background thread is stopped or suspended
// prior to destroying the class object.
//
// # Example
//
// The |ComponentContext| object is typically created early in the startup
// sequence for components, typically after creating the |async::Loop| for the
// main thread.
//
// ```
// int main(int argc, const char** argv) {
//   async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
//   auto context = sys::ComponentContext::Create();
//   my::App app(std::move(context))
//   loop.Run();
//   return 0;
// }
// ```
class ComponentContext final {
 public:
  // Creates a component context that uses |svc| for incoming services. Callers
  // can call |OutgoingDirectory::Serve()| if they wish to publish outgoing
  // directory.
  //
  // This constructor is rarely used directly. Instead, most clients create a
  // component context using the |Create()| static method.
  explicit ComponentContext(std::shared_ptr<ServiceDirectory> svc,
                            async_dispatcher_t* dispatcher = nullptr);

  // Creates a component context that uses |svc| for incoming services and
  // serves outgoing requests over |directory_request|. Callers should be
  // careful to publish outgoing service in |outgoing()| before |dispatcher|
  // starts processing incoming requests for the outgoing services.
  ComponentContext(std::shared_ptr<ServiceDirectory> svc, zx::channel directory_request,
                   async_dispatcher_t* dispatcher = nullptr);

  ~ComponentContext();

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

  // Creates a component context from the process startup info.
  //
  // Call this function once during process initialization to retrieve the
  // handles supplied to the component by the component manager. This function
  // consumes some of those handles, which means subsequent calls to this
  // function will not return a functional component context.
  //
  // Prefer creating the |ComponentContext| in the |main| function for a
  // component and passing the context to a class named "App" which encapsulates
  // the main logic of the program. This pattern makes testing easier because
  // tests can pass a fake |ComponentContext| from |ComponentContextProvider| to
  // the |App| class to inject dependencies.
  //
  // The returned unique_ptr is never null.
  //
  // # Example
  //
  // ```
  // int main(int argc, const char** argv) {
  //   async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  //   auto context = sys::ComponentContext::Create();
  //   my::App app(std::move(context))
  //   loop.Run();
  //   return 0;
  // }
  // ```
  static std::unique_ptr<ComponentContext> Create();

  // The component's incoming directory of services from its namespace.
  //
  // Use this object to connect to services offered by other components.
  //
  // The returned object is thread-safe.
  //
  // # Example
  //
  // ```
  // auto controller = context.svc()->Connect<fuchsia::foo::Controller>();
  // ```
  const std::shared_ptr<ServiceDirectory>& svc() const { return svc_; }

  // The component's outgoing directory.
  //
  // Use this object to publish services and data to the component manager and
  // other components.
  //
  // The returned object is thread-safe.
  //
  // # Example
  //
  // ```
  // class App : public fuchsia::foo::Controller {
  //  public:
  //   App(std::unique_ptr<ComponentContext> context)
  //     : context_(std::move(context) {
  //     context_.outgoing()->AddPublicService(bindings_.GetHandler(this));
  //   }
  //
  //   // fuchsia::foo::Controller implementation:
  //   [...]
  //
  //  private:
  //   fidl::BindingSet<fuchsia::foo::Controller> bindings_;
  // }
  // ```
  const std::shared_ptr<OutgoingDirectory>& outgoing() const { return outgoing_; }
  std::shared_ptr<OutgoingDirectory>& outgoing() { return outgoing_; }

 private:
  std::shared_ptr<ServiceDirectory> svc_;
  std::shared_ptr<OutgoingDirectory> outgoing_;
};

}  // namespace sys

#endif  // LIB_SYS_CPP_COMPONENT_CONTEXT_H_
