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

#include <fs/synchronous-vfs.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fit/function.h>
#include <lib/fsl/vmo/file.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/channel.h>
#include <src/lib/fxl/macros.h>
#include <src/lib/fxl/memory/ref_ptr.h>
#include <src/lib/fxl/strings/string_view.h>

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

#include "garnet/bin/appmgr/component_container.h"
#include "garnet/bin/appmgr/component_controller_impl.h"
#include "garnet/bin/appmgr/environment_controller_impl.h"
#include "garnet/bin/appmgr/hub/hub_info.h"
#include "garnet/bin/appmgr/hub/realm_hub.h"
#include "garnet/bin/appmgr/namespace.h"
#include "garnet/bin/appmgr/namespace_builder.h"
#include "garnet/bin/appmgr/runner_holder.h"
#include "garnet/bin/appmgr/scheme_map.h"
#include "garnet/lib/cmx/runtime.h"
#include "garnet/lib/loader/package_loader.h"

namespace component {

struct RealmArgs {
  static RealmArgs Make(
      Realm* parent, std::string label, std::string data_path,
      std::string cache_path,
      const std::shared_ptr<sys::ServiceDirectory>& env_services,
      bool run_virtual_console, fuchsia::sys::EnvironmentOptions options);

  static RealmArgs MakeWithAdditionalServices(
      Realm* parent, std::string label, std::string data_path,
      std::string cache_path,
      const std::shared_ptr<sys::ServiceDirectory>& env_services,
      bool run_virtual_console,
      fuchsia::sys::ServiceListPtr additional_services,
      fuchsia::sys::EnvironmentOptions options);

  Realm* parent;
  std::string label;
  std::string data_path;
  std::string cache_path;
  std::shared_ptr<sys::ServiceDirectory> environment_services;
  bool run_virtual_console;
  fuchsia::sys::ServiceListPtr additional_services;
  fuchsia::sys::EnvironmentOptions options;
};

class Realm : public ComponentContainer<ComponentControllerImpl> {
 public:
  Realm(RealmArgs args);
  ~Realm();

  Realm* parent() const { return parent_; }
  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& koid() const { return koid_; }

  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 DuplicateJob() const;

  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);

 private:
  static uint32_t next_numbered_label_;

  RunnerHolder* GetOrCreateRunner(const std::string& runner);
  RunnerHolder* GetRunnerRecursive(const std::string& runner) const;

  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, fsl::SizedVmo& app_data,
      const std::string& app_argv0, zx::channel loader_service,
      fdio_flat_namespace_t* flat, ComponentRequestWrapper component_request,
      fxl::RefPtr<Namespace> ns, ComponentObjectCreatedCallback callback);

  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 OpenInfoDir();

  std::string IsolatedPathForPackage(std::string path_prefix,
                                     const FuchsiaPkgUrl& fp);

  Realm* const parent_;
  fuchsia::sys::LoaderPtr loader_;
  std::string label_;
  std::string data_path_;
  std::string cache_path_;
  std::string koid_;
  const bool run_virtual_console_;
  std::unique_ptr<component::PackageLoader> package_loader_;

  zx::job job_;

  fxl::RefPtr<Namespace> default_namespace_;

  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_;

  bool allow_parent_runners_ = false;
  bool delete_storage_on_death_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(Realm);
};

}  // namespace component

#endif  // GARNET_BIN_APPMGR_REALM_H_
