// 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 <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/scenic/snapshot/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/views/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 <src/lib/fxl/macros.h>

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

#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.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(fit::function<void()> done);

  // Called by ModuleControllerImpl and ModuleContextImpl.
  void FocusModule(const std::vector<std::string>& module_path);

  // Called by ModuleControllerImpl.
  void DefocusModule(const std::vector<std::string>& module_path);

  // Called by ModuleControllerImpl.
  void StopModule(const std::vector<std::string>& module_path,
                  fit::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 std::vector<std::string>& module_path, std::string name);

  // Called by ModuleContextImpl.
  void EmbedModule(
      AddModParams add_mod_params,
      fidl::InterfaceRequest<fuchsia::modular::ModuleController>
          module_controller_request,
      fuchsia::ui::views::ViewToken view_token,
      fit::function<void(fuchsia::modular::StartModuleStatus)> callback);

  // Called by ModuleContextImpl.
  void AddModuleToStory(
      AddModParams add_mod_params,
      fidl::InterfaceRequest<fuchsia::modular::ModuleController>
          module_controller_request,
      fit::function<void(fuchsia::modular::StartModuleStatus)> callback);

  // Stops the module at |module_path| in response to a call to
  // |ModuleContext.RemoveSelfFromStory|.
  void RemoveModuleFromStory(const std::vector<std::string>& 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(
      std::string type, fuchsia::mem::Buffer data,
      fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
      fit::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:
  // Operations implemented here.
  class AddIntentCall;
  class DefocusCall;
  class FocusCall;
  class KillModuleCall;
  class LaunchModuleCall;
  class LaunchModuleInShellCall;
  class OnModuleDataUpdatedCall;
  class ResolveParameterCall;
  class StartCall;
  class StopCall;
  class StopModuleCall;
  class StopModuleAndStoryIfEmptyCall;
  class StartSnapshotLoaderCall;
  class UpdateSnapshotCall;

  // 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;
    fuchsia::ui::views::ViewHolderToken module_pending_view_holder_token;
  };

  // A module's story shell-related information that we pend until we are able
  // to pass it off to the story shell.
  struct PendingViewForStoryShell {
    std::vector<std::string> module_path;
    fuchsia::modular::ModuleManifestPtr module_manifest;
    fuchsia::modular::SurfaceRelationPtr surface_relation;
    fuchsia::modular::ModuleSource module_source;
    fuchsia::ui::views::ViewHolderToken view_holder_token;
  };

  // |StoryController|
  void Stop(StopCallback done) override;
  void GetInfo(GetInfoCallback callback) override;
  void RequestStart() override;
  void TakeAndLoadSnapshot(fuchsia::ui::views::ViewToken view_token,
                           TakeAndLoadSnapshotCallback done) override;
  void Watch(
      fidl::InterfaceHandle<fuchsia::modular::StoryWatcher> watcher) override;
  void GetActiveModules(GetActiveModulesCallback callback) override;
  void GetModules(GetModulesCallback callback) override;
  void GetModuleController(
      std::vector<std::string> module_path,
      fidl::InterfaceRequest<fuchsia::modular::ModuleController> request)
      override;
  void GetLink(fuchsia::modular::LinkPath link_path,
               fidl::InterfaceRequest<fuchsia::modular::Link> request) override;

  // Communicates with SessionShell.
  void StartStoryShell();
  void DetachView(fit::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 ProcessPendingStoryShellViews();
  std::set<fuchsia::modular::LinkPath> GetActiveLinksInternal();

  bool IsExternalModule(const std::vector<std::string>& 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();

  // 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 std::vector<std::string>& 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 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_;

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

  // Everything for the story shell. Relationships between modules are conveyed
  // to the story shell using their instance IDs.
  std::unique_ptr<AsyncHolderBase> story_shell_holder_;
  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_;

  // Since story shell cannot display views whose parents are not yet displayed,
  // |pending_story_shell_views_| holds the view of a non-embedded running
  // module (identified by its serialized module path) until its parent is
  // connected to story shell.
  std::map<std::string, PendingViewForStoryShell> pending_story_shell_views_;

  std::vector<RunningModInfo> running_mod_infos_;

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

  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_
