// 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 "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/lib/loader/package_loader.h"
#include "src/lib/storage/vfs/cpp/synchronous_vfs.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"
#include "src/sys/appmgr/util.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,
                        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,
      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,
      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;
  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() override;

  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,
      const 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.
  fpromise::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);

  static void InstallRuntime(Realm* realm, zx::job child_job, zx::process process,
                             fxl::RefPtr<Namespace> ns, fdio_flat_namespace_t* flat,
                             std::string args, ComponentRequestWrapper component_request,
                             std::string url, ExportedDirChannels channels,
                             ComponentObjectCreatedCallback callback, zx::channel pkg_handle,
                             zx::channel exception_channel);

 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(const 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,
      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 an exception channel 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 RegisterExceptionChannelForCrashIntrospection(
      zx::channel exception_channel, 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_;
  std::optional<component::PackageLoader> package_loader_;
  std::optional<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_;

  // GWP-ASan configuration. If not empty, it is an environment variable (SCUDO_OPTIONS) that will
  // be injected to all the ELF binary components.
  std::string gwp_asan_config_;

  FXL_DISALLOW_COPY_AND_ASSIGN(Realm);
};

}  // namespace component

#endif  // SRC_SYS_APPMGR_REALM_H_
