// 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 <zx/channel.h>

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

#include <fuchsia/sys/cpp/fidl.h>
#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"
#include "lib/fidl/cpp/binding_set.h"
#include "lib/fit/function.h"
#include "lib/fsl/vmo/file.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/strings/string_view.h"
#include "lib/svc/cpp/service_provider_bridge.h"

namespace component {

struct RealmArgs {
  static RealmArgs Make(
      Realm* parent, std::string label,
      const std::shared_ptr<component::Services>& env_services,
      bool run_virtual_console, bool inherit_parent_services, bool kill_on_oom);

  static RealmArgs MakeWithAdditionalServices(
      Realm* parent, std::string label,
      const std::shared_ptr<component::Services>& env_services,
      bool run_virtual_console,
      fuchsia::sys::ServiceListPtr additional_services,
      bool inherit_parent_services, bool kill_on_oom);

  Realm* parent;
  std::string label;
  std::shared_ptr<component::Services> environment_services;
  bool run_virtual_console;
  fuchsia::sys::ServiceListPtr additional_services;
  bool inherit_parent_services;
  bool allow_parent_runners;
  bool kill_on_oom;
};

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

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

  std::shared_ptr<component::Services> 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(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.
  std::unique_ptr<ComponentControllerImpl> ExtractComponent(
      ComponentControllerImpl* controller) override;

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

  zx_status_t BindSvc(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, ExportedDirType exported_dir_layout,
      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();

  Realm* const parent_;
  fuchsia::sys::LoaderPtr loader_;
  std::string label_;
  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::unique_ptr<ComponentControllerImpl>>
      applications_;

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

  zx::channel svc_channel_client_;
  zx::channel svc_channel_server_;

  SchemeMap scheme_map_;

  const std::shared_ptr<component::Services> environment_services_;

  bool allow_parent_runners_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(Realm);
};

}  // namespace component

#endif  // GARNET_BIN_APPMGR_REALM_H_
