// Copyright 2016 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_REALM_H_
#define SRC_SYS_APPMGR_REALM_H_

#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/sys/internal/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fit/function.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/channel.h>
#include <lib/zx/status.h>
#include <zircon/syscalls/policy.h>
#include <zircon/types.h>

#include <iosfwd>
#include <memory>
#include <string>
#include <unordered_map>

#include <fbl/unique_fd.h>
#include <fs/synchronous_vfs.h>

#include "garnet/lib/loader/package_loader.h"
#include "src/lib/cmx/runtime.h"
#include "src/lib/fsl/vmo/file.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/sys/appmgr/cache_control.h"
#include "src/sys/appmgr/component_container.h"
#include "src/sys/appmgr/component_controller_impl.h"
#include "src/sys/appmgr/component_event_provider_impl.h"
#include "src/sys/appmgr/component_id_index.h"
#include "src/sys/appmgr/cpu_watcher.h"
#include "src/sys/appmgr/crash_introspector.h"
#include "src/sys/appmgr/environment_controller_impl.h"
#include "src/sys/appmgr/hub/hub_info.h"
#include "src/sys/appmgr/hub/realm_hub.h"
#include "src/sys/appmgr/log_connector_impl.h"
#include "src/sys/appmgr/moniker.h"
#include "src/sys/appmgr/namespace.h"
#include "src/sys/appmgr/namespace_builder.h"
#include "src/sys/appmgr/runner_holder.h"
#include "src/sys/appmgr/scheme_map.h"

namespace component {
class ComponentEventProviderImpl;

namespace internal {

constexpr char kRootLabel[] = "app";

// When a component event will be triggered, this struct will contain what provider to notify and
// with which component identity data.
struct EventNotificationInfo {
  ComponentEventProviderImpl* provider;
  fuchsia::sys::internal::SourceIdentity component;
};

enum class StorageType { DATA, CACHE, TEMP };

}  // namespace internal

struct RealmArgs {
  static RealmArgs Make(fxl::WeakPtr<Realm> parent, std::string label, std::string data_path,
                        std::string cache_path, std::string temp_path,
                        const std::shared_ptr<sys::ServiceDirectory>& env_services,
                        bool run_virtual_console, fuchsia::sys::EnvironmentOptions options,
                        fbl::unique_fd appmgr_config_dir,
                        fbl::RefPtr<ComponentIdIndex> component_id_index);

  static RealmArgs MakeWithAdditionalServices(
      fxl::WeakPtr<Realm> parent, std::string label, std::string data_path, std::string cache_path,
      std::string temp_path, const std::shared_ptr<sys::ServiceDirectory>& env_services,
      bool run_virtual_console, fuchsia::sys::ServiceListPtr additional_services,
      fuchsia::sys::EnvironmentOptions options, fbl::unique_fd appmgr_config_dir,
      fbl::RefPtr<ComponentIdIndex> component_id_index);

  static RealmArgs MakeWithCustomLoader(
      fxl::WeakPtr<Realm> parent, std::string label, std::string data_path, std::string cache_path,
      std::string temp_path, const std::shared_ptr<sys::ServiceDirectory>& env_services,
      bool run_virtual_console, fuchsia::sys::ServiceListPtr additional_services,
      fuchsia::sys::EnvironmentOptions options, fbl::unique_fd appmgr_config_dir,
      fbl::RefPtr<ComponentIdIndex> component_id_index, fuchsia::sys::LoaderPtr loader);

  fxl::WeakPtr<Realm> parent;
  std::string label;
  std::string data_path;
  std::string cache_path;
  std::string temp_path;
  std::shared_ptr<sys::ServiceDirectory> environment_services;
  bool run_virtual_console;
  fuchsia::sys::ServiceListPtr additional_services;
  fuchsia::sys::EnvironmentOptions options;
  fbl::unique_fd appmgr_config_dir;
  CpuWatcher* cpu_watcher;
  fbl::RefPtr<ComponentIdIndex> component_id_index;
  std::optional<fuchsia::sys::LoaderPtr> loader;
};

class Realm : public ComponentContainer<ComponentControllerImpl> {
 public:
  using ShutdownNamespaceCallback = fit::callback<void()>;
  static std::unique_ptr<Realm> Create(RealmArgs args);

  // Constructor to create a Realm object. Clients should call |Create|.
  Realm(RealmArgs args, zx::job job);

  ~Realm();

  fxl::WeakPtr<Realm> parent() const { return parent_; }
  CpuWatcher* cpu_watcher() const { return cpu_watcher_; }
  const std::string& label() const { return label_; }
  const std::string& data_path() const { return data_path_; }
  const std::string& cache_path() const { return cache_path_; }
  const std::string& temp_path() const { return temp_path_; }
  const std::string& koid() const { return koid_; }
  const fbl::RefPtr<LogConnectorImpl>& log_connector() const { return log_connector_; }

  const fbl::RefPtr<fs::PseudoDir>& hub_dir() const { return hub_.dir(); }

  std::shared_ptr<sys::ServiceDirectory> environment_services() const {
    return environment_services_;
  }

  HubInfo HubInfo();

  zx::job DuplicateJobForHub() const;

  const zx::job& job() const { return job_; }
  const std::unordered_map<ComponentControllerImpl*, std::shared_ptr<ComponentControllerImpl>>&
  applications() const {
    return applications_;
  }

  const std::unordered_map<std::string, std::unique_ptr<RunnerHolder>>& runners() const {
    return runners_;
  }

  const std::unordered_map<Realm*, std::unique_ptr<EnvironmentControllerImpl>>& children() const {
    return children_;
  }

  fxl::WeakPtr<Realm> weak_ptr() { return weak_ptr_factory_.GetWeakPtr(); }

  void CreateNestedEnvironment(
      fidl::InterfaceRequest<fuchsia::sys::Environment> environment,
      fidl::InterfaceRequest<fuchsia::sys::EnvironmentController> controller_request,
      std::string label, fuchsia::sys::ServiceListPtr additional_services,
      fuchsia::sys::EnvironmentOptions options);

  using ComponentObjectCreatedCallback =
      fit::function<void(std::weak_ptr<ComponentControllerImpl> component)>;

  void CreateComponent(fuchsia::sys::LaunchInfo launch_info,
                       fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller,
                       ComponentObjectCreatedCallback callback = nullptr);

  // Removes the child realm from this realm and returns the owning
  // reference to the child's controller. The caller of this function
  // typically destroys the controller (and hence the environment) shortly
  // after calling this function.
  std::unique_ptr<EnvironmentControllerImpl> ExtractChild(Realm* child);

  // Removes the application from this environment and returns the owning
  // reference to the application's controller. The caller of this function
  // typically destroys the controller (and hence the application) shortly after
  // calling this function.
  // We use shared_ptr so that we can pass weak_ptrs to dependent code.
  std::shared_ptr<ComponentControllerImpl> ExtractComponent(
      ComponentControllerImpl* controller) override;

  void AddBinding(fidl::InterfaceRequest<fuchsia::sys::Environment> environment);

  // Binds the given channel to the services directory (/svc) for the very first
  // nested realm created. This function is only supported for the root realm,
  // otherwise it will do nothing and return ZX_ERR_NOT_SUPPORTED.
  zx_status_t BindFirstNestedRealmSvc(zx::channel channel);

  void CreateShell(const std::string& path, zx::channel svc);

  void Resolve(fidl::StringPtr name, fuchsia::process::Resolver::ResolveCallback callback);

  // Notifies the |ComponentEventListener| of this realm or the closest parent realm (if there's
  // one) with a component out/diagnostics directory when the directory is available.
  void NotifyComponentDiagnosticsDirReady(const std::string& component_url,
                                          const std::string& component_name,
                                          const std::string& instance_id,
                                          fidl::InterfaceHandle<fuchsia::io::Directory> directory);

  // Notifies the Realm components event subscriber when a component starts.
  void NotifyComponentStarted(const std::string& component_url, const std::string& component_name,
                              const std::string& instance_id);

  // Notifies the Realm components event subscriber when a component stops.
  void NotifyComponentStopped(const std::string& component_url, const std::string& component_name,
                              const std::string& instance_id);

  // Creates a connection to |fuchsia::sys::internal::ComponentEventProvider|.
  zx_status_t BindComponentEventProvider(
      fidl::InterfaceRequest<fuchsia::sys::internal::ComponentEventProvider> request);

  // Whether a `ComponentEventListener` has been bound to this realm `ComponentEventProvider`.
  bool HasComponentEventListenerBound();

  // Given a component url |fp|, initializes and returns the component's absolute storage
  // directory for the given |storage_path|. Returns an error if the directory could not be made.
  //
  // A component instance's storage directory is in one of two places:
  //  (a) A directory keyed using component instance ID, if it has one.
  //  (b) A directory computed using fn(realm_path, component URL)
  //
  // If a component is assigned an instance ID while it already has a storage
  // directory under (b), its storage directory is moved to (a).
  //
  // Note: This method is public only for the purposes for testing storage paths and migration
  // logic.
  fit::result<std::string, zx_status_t> InitIsolatedPathForComponentInstance(
      const FuchsiaPkgUrl& fp, internal::StorageType storage_type);

  // Shutdown realm's namespace processing all pending messages.
  void ShutdownNamespace(ShutdownNamespaceCallback callback = nullptr);

  static Moniker ComputeMoniker(Realm* realm, const FuchsiaPkgUrl& fp);

 private:
  static uint32_t next_numbered_label_;

  // Returns |runner| if it exists in |runners_|, otherwise creates a runner in
  // |runners_|. If |use_parent_runners_| is true, creates |runner| in
  // |parent_->runners_|.
  RunnerHolder* GetOrCreateRunner(const std::string& runner);
  Realm* GetRunnerRealm();

  void CreateComponentWithRunnerForScheme(std::string runner_url,
                                          fuchsia::sys::LaunchInfo launch_info,
                                          ComponentRequestWrapper component_request,
                                          ComponentObjectCreatedCallback callback);

  void CreateComponentFromPackage(fuchsia::sys::PackagePtr package,
                                  fuchsia::sys::LaunchInfo launch_info,
                                  ComponentRequestWrapper component_request,
                                  ComponentObjectCreatedCallback callback);

  void CreateElfBinaryComponentFromPackage(
      fuchsia::sys::LaunchInfo launch_info, zx::vmo executable, const std::string& app_argv0,
      const std::vector<std::string>& env_vars, zx::channel loader_service,
      fdio_flat_namespace_t* flat, ComponentRequestWrapper component_request,
      fxl::RefPtr<Namespace> ns, const std::vector<zx_policy_basic_v2_t>& policies,
      ComponentObjectCreatedCallback callback, zx::channel package_handle);

  void CreateRunnerComponentFromPackage(
      fuchsia::sys::PackagePtr package, fuchsia::sys::LaunchInfo launch_info,
      RuntimeMetadata& runtime, fuchsia::sys::FlatNamespace flat,
      ComponentRequestWrapper component_request, fxl::RefPtr<Namespace> ns,
      fidl::VectorPtr<fuchsia::sys::ProgramMetadata> program_metadata, zx::channel package_handle);

  // When a component event will be triggered, this finds what provider to notify and with what
  // identity data. The provider will be either the one attached to this component or some
  // provider in an ancestor realm.
  internal::EventNotificationInfo GetEventNotificationInfo(const std::string& component_url,
                                                           const std::string& component_name,
                                                           const std::string& instance_id);

  zx::channel OpenInfoDir();

  // Called by `FindComponent`. This function returns realm path in reverse order.
  zx::status<fuchsia::sys::internal::SourceIdentity> FindComponentInternal(zx_koid_t process_koid);

  // Registers a job for crash introspection.
  // This internally adds realm label to passed |component_info| and calls either it's own parent
  // or directly calls introspector if this is a root realm.
  void RegisterJobForCrashIntrospection(const zx::job& job,
                                        fuchsia::sys::internal::SourceIdentity component_info);

  fxl::WeakPtr<Realm> const parent_;
  fuchsia::sys::LoaderPtr loader_;
  std::string label_;
  std::string data_path_;
  std::string cache_path_;
  std::string temp_path_;
  std::string koid_;
  std::vector<std::string> realm_path_;
  const bool run_virtual_console_;
  std::unique_ptr<component::PackageLoader> package_loader_;
  std::unique_ptr<component::CacheControl> cache_control_;
  fbl::RefPtr<LogConnectorImpl> log_connector_;

  zx::job job_;

  fxl::RefPtr<Namespace> default_namespace_;

  std::unique_ptr<component::ComponentEventProviderImpl> component_event_provider_;

  RealmHub hub_;
  fs::SynchronousVfs info_vfs_;

  std::unordered_map<Realm*, std::unique_ptr<EnvironmentControllerImpl>> children_;

  std::unordered_map<ComponentControllerImpl*, std::shared_ptr<ComponentControllerImpl>>
      applications_;

  std::unordered_map<std::string, std::unique_ptr<RunnerHolder>> runners_;

  // This channel pair is only created for the root realm, and is used to
  // implement BindFirstNestedRealmSvc. The server end is used to serve the
  // services directory (/svc) for the first nested realm created.
  zx::channel first_nested_realm_svc_client_;
  zx::channel first_nested_realm_svc_server_;

  SchemeMap scheme_map_;

  const std::shared_ptr<sys::ServiceDirectory> environment_services_;

  fbl::unique_fd appmgr_config_dir_;

  bool use_parent_runners_ = false;
  bool delete_storage_on_death_ = false;

  // Pointer to a cpu watcher to register and unregister components for sampling.
  // Not owned.
  CpuWatcher* const cpu_watcher_;

  fbl::RefPtr<ComponentIdIndex> component_id_index_;

  fxl::WeakPtrFactory<Realm> weak_ptr_factory_;

  // Implement crash introspect service. Only initialized in root realm.
  std::unique_ptr<CrashIntrospector> crash_introspector_;

  FXL_DISALLOW_COPY_AND_ASSIGN(Realm);
};

}  // namespace component

#endif  // SRC_SYS_APPMGR_REALM_H_
