// 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.

// The Story service is the context in which a story executes. It
// starts modules and provides them with a handle to itself, so they
// can start more modules. It also serves as the factory for
// fuchsia::modular::Link instances, which are used to share data between
// modules.

#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_CONTROLLER_IMPL_H_
#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_CONTROLLER_IMPL_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/scenic/snapshot/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
#include <lib/async/cpp/operation.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fidl/cpp/interface_ptr_set.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fxl/macros.h>

#include "peridot/bin/sessionmgr/storage/session_storage.h"
#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
#include "peridot/bin/sessionmgr/story/model/story_observer.h"
#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
#include "peridot/bin/sessionmgr/story_runner/ongoing_activity_impl.h"
#include "peridot/bin/sessionmgr/story_runner/story_shell_context_impl.h"
#include "peridot/lib/fidl/app_client.h"
#include "peridot/lib/fidl/environment.h"
#include "peridot/lib/ledger_client/ledger_client.h"
#include "peridot/lib/ledger_client/page_client.h"
#include "peridot/lib/ledger_client/types.h"

namespace modular {

class ModuleContextImpl;
class ModuleControllerImpl;
class StoryModelMutator;
class StoryProviderImpl;
class StoryStorage;
class StoryVisibilitySystem;

// The story runner, which holds all the links and runs all the modules as well
// as the story shell. It also implements the StoryController service to give
// clients control over the story.
class StoryControllerImpl : fuchsia::modular::StoryController {
 public:
  StoryControllerImpl(SessionStorage* session_storage,
                      StoryStorage* story_storage,
                      std::unique_ptr<StoryMutator> story_mutator,
                      std::unique_ptr<StoryObserver> story_observer,
                      StoryVisibilitySystem* story_visibility_system,
                      StoryProviderImpl* story_provider_impl);
  ~StoryControllerImpl() override;

  // Called by StoryProviderImpl.
  void Connect(
      fidl::InterfaceRequest<fuchsia::modular::StoryController> request);

  // Called by StoryProviderImpl.
  bool IsRunning();

  // Called by StoryProviderImpl.
  //
  // Returns a list of the ongoing activities in this story.
  fidl::VectorPtr<fuchsia::modular::OngoingActivityType> GetOngoingActivities();

  void Sync(const std::function<void()>& done);

  // Called by ModuleControllerImpl and ModuleContextImpl.
  void FocusModule(const fidl::VectorPtr<fidl::StringPtr>& module_path);

  // Called by ModuleControllerImpl.
  void DefocusModule(const fidl::VectorPtr<fidl::StringPtr>& module_path);

  // Called by ModuleControllerImpl.
  void StopModule(const fidl::VectorPtr<fidl::StringPtr>& module_path,
                  const std::function<void()>& done);

  // Called by ModuleControllerImpl.
  //
  // Releases ownership of |controller| and cleans up any related internal
  // storage. It is the caller's responsibility to delete |controller|.
  void ReleaseModule(ModuleControllerImpl* module_controller_impl);

  // Called by ModuleContextImpl.
  fidl::StringPtr GetStoryId() const;

  // Called by ModuleContextImpl.
  void RequestStoryFocus();

  // Called by ModuleContextImpl.
  void ConnectLinkPath(fuchsia::modular::LinkPathPtr link_path,
                       fidl::InterfaceRequest<fuchsia::modular::Link> request);

  // Called by ModuleContextImpl.
  fuchsia::modular::LinkPathPtr GetLinkPathForParameterName(
      const fidl::VectorPtr<fidl::StringPtr>& module_path,
      fidl::StringPtr name);

  // Called by ModuleContextImpl.
  void EmbedModule(
      const fidl::VectorPtr<fidl::StringPtr>& parent_module_path,
      fidl::StringPtr module_name, fuchsia::modular::IntentPtr intent,
      fidl::InterfaceRequest<fuchsia::modular::ModuleController>
          module_controller_request,
      fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
          view_owner_request,
      fuchsia::modular::ModuleSource module_source,
      std::function<void(fuchsia::modular::StartModuleStatus)> callback);

  // Called by ModuleContextImpl.
  void StartModule(
      const fidl::VectorPtr<fidl::StringPtr>& parent_module_path,
      fidl::StringPtr module_name, fuchsia::modular::IntentPtr intent,
      fidl::InterfaceRequest<fuchsia::modular::ModuleController>
          module_controller_request,
      fuchsia::modular::SurfaceRelationPtr surface_relation,
      fuchsia::modular::ModuleSource module_source,
      std::function<void(fuchsia::modular::StartModuleStatus)> callback);

  // Called by ModuleContextImpl.
  void StartContainerInShell(
      const fidl::VectorPtr<fidl::StringPtr>& parent_module_path,
      fidl::StringPtr name,
      fuchsia::modular::SurfaceRelationPtr parent_relation,
      fidl::VectorPtr<fuchsia::modular::ContainerLayout> layout,
      fidl::VectorPtr<fuchsia::modular::ContainerRelationEntry> relationships,
      fidl::VectorPtr<fuchsia::modular::ContainerNodePtr> nodes);

  // Stops the module at |module_path| in response to a call to
  // |ModuleContext.RemoveSelfFromStory|.
  void RemoveModuleFromStory(
      const fidl::VectorPtr<fidl::StringPtr>& module_path);

  // Called by ModuleContextImpl.
  void StartOngoingActivity(
      const fuchsia::modular::OngoingActivityType ongoing_activity_type,
      fidl::InterfaceRequest<fuchsia::modular::OngoingActivity> request);

  // Called by ModuleContextImpl.
  void CreateEntity(
      fidl::StringPtr type, fuchsia::mem::Buffer data,
      fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
      std::function<void(std::string /* entity_reference */)> callback);

  // Stops the story as part of a story provider operation. The story provider
  // can indicate whether this is part of an operation where all stories are
  // stopped at once in order to stop the session shell, indicated by bulk being
  // true. Happens at logout or when session shells are swapped. In that
  // situation, DetachView() is not called for this story.
  void StopBulk(bool bulk, StopCallback done);

 private:
  // |StoryController|
  void Stop(StopCallback done) override;

  // |StoryController|
  void GetInfo(GetInfoCallback callback) override;
  void Start(fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
                 request) override;
  void RequestStart() override;
  void TakeAndLoadSnapshot(
      fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request,
      TakeAndLoadSnapshotCallback done) override;
  void Watch(
      fidl::InterfaceHandle<fuchsia::modular::StoryWatcher> watcher) override;
  void GetActiveModules(GetActiveModulesCallback callback) override;
  void GetModules(GetModulesCallback callback) override;
  void GetModuleController(
      fidl::VectorPtr<fidl::StringPtr> module_path,
      fidl::InterfaceRequest<fuchsia::modular::ModuleController> request)
      override;
  void GetActiveLinks(
      fidl::InterfaceHandle<fuchsia::modular::StoryLinksWatcher> watcher,
      GetActiveLinksCallback callback) override;
  void GetLink(fuchsia::modular::LinkPath link_path,
               fidl::InterfaceRequest<fuchsia::modular::Link> request) override;

  // Communicates with SessionShell.
  void StartStoryShell(
      fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request);
  void DetachView(std::function<void()> done);

  // Called whenever |story_storage_| sees an updated ModuleData from another
  // device.
  void OnModuleDataUpdated(fuchsia::modular::ModuleData module_data);

  // Misc internal helpers.
  void SetRuntimeState(fuchsia::modular::StoryState new_state);
  void NotifyStoryWatchers(
      const fuchsia::modular::storymodel::StoryModel& model);
  void NotifyOneStoryWatcher(
      const fuchsia::modular::storymodel::StoryModel& model,
      fuchsia::modular::StoryWatcher* watcher);
  void ProcessPendingViews();
  std::set<fuchsia::modular::LinkPath> GetActiveLinksInternal();

  bool IsExternalModule(const fidl::VectorPtr<fidl::StringPtr>& module_path);

  // Handles SessionShell OnModuleFocused event that indicates whether or not a
  // surface was focused.
  void OnSurfaceFocused(fidl::StringPtr surface_id);

  // Initializes the Environment under which all new processes in the story are
  // launched. Use |story_environment_| to manipulate the environment's
  // services.
  void InitStoryEnvironment();

  // Destroys the Environment created for this story, tearing down all
  // processes.
  void DestroyStoryEnvironment();

  // The ID of the story, copied from |story_observer_| for convenience in
  // transitioning clients.  TODO(thatguy): Remove users of this in favor of
  // reading from the |story_observer_| directly.
  const fidl::StringPtr story_id_;

  // True once AttachView() was called. Temporarily needed during transition
  // from Start() to RequestStart(), will be removed once Start() is removed.
  // Cf. MF-121.
  bool needs_detach_view_{};

  StoryProviderImpl* const story_provider_impl_;  // Not owned.

  SessionStorage* const session_storage_;  // Not owned.
  StoryStorage* const story_storage_;      // Not owned.

  std::unique_ptr<StoryMutator> story_mutator_;
  std::unique_ptr<StoryObserver> story_observer_;
  StoryVisibilitySystem* const story_visibility_system_;  // Not owned.

  // The application environment (which abstracts a zx::job) in which the
  // modules within this story run. This environment is only valid (not null) if
  // the story is running.
  std::unique_ptr<Environment> story_environment_;

  // Implements the primary service provided here:
  // fuchsia::modular::StoryController.
  fidl::BindingSet<fuchsia::modular::StoryController> bindings_;

  // Watcher for various aspects of the story.
  fidl::InterfacePtrSet<fuchsia::modular::StoryWatcher> watchers_;
  fidl::InterfacePtrSet<fuchsia::modular::StoryLinksWatcher> links_watchers_;

  // Everything for the story shell. Relationships between modules are conveyed
  // to the story shell using their instance IDs.
  std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> story_shell_app_;
  fuchsia::modular::StoryShellPtr story_shell_;

  StoryShellContextImpl story_shell_context_impl_;

  // The module instances (identified by their serialized module paths) already
  // known to story shell. Does not include modules whose views are pending and
  // not yet sent to story shell.
  std::set<fidl::StringPtr> connected_views_;

  // Holds the view of a non-embedded running module (identified by its
  // serialized module path) until its parent is connected to story shell. Story
  // shell cannot display views whose parents are not yet displayed.
  struct PendingView {
    fidl::VectorPtr<fidl::StringPtr> module_path;
    fuchsia::modular::ModuleManifestPtr module_manifest;
    fuchsia::modular::SurfaceRelationPtr surface_relation;
    fuchsia::modular::ModuleSource module_source;
    fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner;
  };
  std::map<fidl::StringPtr, PendingView> pending_views_;

  // The first ingredient of a story: Modules. For each *running* Module in the
  // Story, there is one RunningModInfo.
  struct RunningModInfo {
    // NOTE: |module_data| is a cached copy of what is stored in
    // |story_storage_|, the source of truth. It is updated in two
    // places:
    //
    // 1) In LaunchModuleCall (used by LaunchModuleInShellCall) in the case
    // that either a) the module isn't running yet or b) ModuleData.intent
    // differs from what is cached.
    //
    // 2) Indirectly from OnModuleDataUpdated(), which is called when another
    // device updates the Module by calling LaunchModuleInShellCall. However,
    // this only happens if the Module is EXTERNAL (it was not explicitly added
    // by another Module).
    //
    // TODO(thatguy): we should ensure that the local cached copy is always
    // up to date no matter what.
    fuchsia::modular::ModuleDataPtr module_data;
    std::unique_ptr<ModuleContextImpl> module_context_impl;
    std::unique_ptr<ModuleControllerImpl> module_controller_impl;
  };
  std::vector<RunningModInfo> running_mod_infos_;

  // Finds the active RunningModInfo for a module at the given module path. May
  // return nullptr if the module at the path is not running, regardless of
  // whether a module at that path is known to the story.
  RunningModInfo* FindRunningModInfo(
      const fidl::VectorPtr<fidl::StringPtr>& module_path);

  // Finds the active RunningModInfo for the story shell anchor of a module
  // with the given |running_mod_info|. The anchor is the closest ancestor
  // module of the given module that is not embedded and actually known to the
  // story shell. This requires that it must be running, otherwise it cannot be
  // connected to the story shell. May return nullptr if the anchor module, or
  // any intermediate module, is not running, regardless of whether a module at
  // such path is known to the story.
  RunningModInfo* FindAnchor(RunningModInfo* running_mod_info);

  // The second ingredient of a story: Links. They connect Modules.
  fidl::BindingSet<Link, std::unique_ptr<LinkImpl>> link_impls_;

  // This is the source of truth on which activities are currently ongoing in
  // the story's modules.
  fidl::BindingSet<fuchsia::modular::OngoingActivity,
                   std::unique_ptr<OngoingActivityImpl>>
      ongoing_activities_;

  // Used to load snapshots.
  fuchsia::scenic::snapshot::LoaderPtr snapshot_loader_;

  // A collection of services, scoped to this Story, for use by intelligent
  // Modules.
  fuchsia::modular::IntelligenceServicesPtr intelligence_services_;

  // Asynchronous operations are sequenced in a queue.
  OperationQueue operation_queue_;

  fxl::WeakPtrFactory<StoryControllerImpl> weak_factory_;

  // Operations implemented here.
  class AddIntentCall;
  class DefocusCall;
  class FocusCall;
  class KillModuleCall;
  class LaunchModuleCall;
  class LaunchModuleInShellCall;
  class OnModuleDataUpdatedCall;
  class ResolveParameterCall;
  class StartCall;
  class StartContainerInShellCall;
  class StopCall;
  class StopModuleCall;
  class StopModuleAndStoryIfEmptyCall;
  class StartSnapshotLoaderCall;
  class UpdateSnapshotCall;

  FXL_DISALLOW_COPY_AND_ASSIGN(StoryControllerImpl);
};

// NOTE: This is only exposed publicly for testing.
bool ShouldRestartModuleForNewIntent(
    const fuchsia::modular::Intent& old_intent,
    const fuchsia::modular::Intent& new_intent);

}  // namespace modular

#endif  // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_CONTROLLER_IMPL_H_
