// Copyright 2018 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_SYS_APPMGR_SERVICE_PROVIDER_DIR_IMPL_H_
#define SRC_SYS_APPMGR_SERVICE_PROVIDER_DIR_IMPL_H_

#include <fuchsia/sys/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>

#include <string>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>

#include "lib/fidl/cpp/binding_set.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/service.h"
#include "src/lib/storage/vfs/cpp/synchronous_vfs.h"
#include "src/lib/storage/vfs/cpp/vfs_types.h"
#include "src/sys/appmgr/log_connector_impl.h"
#include "src/sys/appmgr/moniker.h"

namespace component {

constexpr char kUnknownComponent[] = "<unknown v2 component>";

// A directory-like object which dynamically creates Service vnodes
// for any file lookup. It also exposes service provider interface.
//
// It supports enumeration for only first level of services.
class ServiceProviderDirImpl : public fuchsia::sys::ServiceProvider, public fs::Vnode {
 public:
  explicit ServiceProviderDirImpl(fbl::RefPtr<LogConnectorImpl> log_connector,
                                  const std::vector<std::string>* services = nullptr);
  ~ServiceProviderDirImpl() override;

  // Sets the parent of this. Parent should be fully initialized.
  void set_parent(fbl::RefPtr<ServiceProviderDirImpl> parent);

  const std::string& component_url() const { return component_url_; }

  const std::string& component_moniker() const { return component_moniker_; }

  void set_component_moniker(const Moniker& moniker) {
    component_moniker_ = moniker.ToString();
    component_url_ = moniker.url;
  }
  void set_component_id(const std::string& id) { component_id_ = id; }

  void AddService(const std::string& service_name, fbl::RefPtr<fs::Service> service);

  void AddBinding(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request);

  //
  // Overridden from |fs::Vnode|:
  //

  fs::VnodeProtocolSet GetProtocols() const final;

  zx_status_t Lookup(std::string_view name, fbl::RefPtr<fs::Vnode>* out) final;

  zx_status_t GetAttributes(fs::VnodeAttributes* a) final;

  zx_status_t Readdir(fs::VdirCookie* cookie, void* dirents, size_t len, size_t* out_actual) final;

  zx_status_t GetNodeInfoForProtocol(fs::VnodeProtocol protocol, fs::Rights rights,
                                     fs::VnodeRepresentation* representation) final;

  //
  // Overridden from |fuchsia::sys::ServiceProvider|:
  //

  void ConnectToService(std::string service_name, zx::channel channel) override;

  // Initialize LogConnector and LogSink services if needed. Should be called *after*
  // other namespace setup steps so that parent-provided versions of those services will
  // take precedence.
  void InitLogging();

  bool IsServiceAllowlisted(const std::string& service_name) {
    return (!has_services_allowlist_ || services_allowlist_.count(service_name) > 0);
  }

 private:
  fidl::BindingSet<fuchsia::sys::ServiceProvider> bindings_;
  fs::SynchronousVfs vfs_;
  // |root_| has all services offered by this provider (including those
  // inherited from the parent, if any).
  fbl::RefPtr<fs::PseudoDir> root_;
  fbl::RefPtr<ServiceProviderDirImpl> parent_;
  fbl::RefPtr<LogConnectorImpl> log_connector_;
  fxl::WeakPtrFactory<ServiceProviderDirImpl> weak_factory_;

  bool has_builtin_logsink_ = false;

  // TODO(fxbug.dev/3924): Remove has_services_allowlist_ when empty services is
  // equivalent to no services.
  bool has_services_allowlist_ = false;
  std::unordered_set<std::string> services_allowlist_;
  // Secondary storage for services under |root_| in a format that can easily
  // be consumed by children. Stored as vector to preserve order.
  typedef std::pair<std::string, fbl::RefPtr<fs::Service>> ServiceHandle;
  std::vector<ServiceHandle> service_handles_;
  std::unordered_set<std::string> all_service_names_;

  std::set<std::string> service_not_available_warnings_logged_;

  std::string component_moniker_ = kUnknownComponent;
  std::string component_url_ = kUnknownComponent;
  std::string component_id_ = "-1";

  FXL_DISALLOW_COPY_AND_ASSIGN(ServiceProviderDirImpl);
};

}  // namespace component

#endif  // SRC_SYS_APPMGR_SERVICE_PROVIDER_DIR_IMPL_H_
