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

#include <memory>

#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
#include <lib/callback/scoped_callback.h>
#include <lib/component/cpp/connect.h>
#include <lib/component/cpp/startup_context.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fsl/vmo/strings.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/macros.h>

#include "peridot/lib/rapidjson/rapidjson.h"
#include "peridot/lib/testing/component_main.h"
#include "peridot/lib/testing/session_shell_base.h"
#include "peridot/public/lib/integration_testing/cpp/reporting.h"
#include "peridot/public/lib/integration_testing/cpp/testing.h"
#include "peridot/tests/common/defs.h"
#include "peridot/tests/module_context/defs.h"

using ::modular::testing::Await;
using ::modular::testing::Signal;
using ::modular::testing::TestPoint;

namespace {

const char kStoryName[] = "story";

// A simple story activity watcher implementation.
class StoryActivityWatcherImpl : fuchsia::modular::StoryActivityWatcher {
 public:
  StoryActivityWatcherImpl()
      : binding_(this),
        on_notify_(
            [](fidl::StringPtr,
               fidl::VectorPtr<fuchsia::modular::OngoingActivityType>) {}) {}
  ~StoryActivityWatcherImpl() override = default;

  void Watch(fuchsia::modular::StoryProvider* const story_provider) {
    story_provider->WatchActivity(binding_.NewBinding());
  }

  void OnNotify(std::function<
                void(fidl::StringPtr,
                     fidl::VectorPtr<fuchsia::modular::OngoingActivityType>)>
                    on_notify) {
    on_notify_ = std::move(on_notify);
  }

 private:
  // |fuchsia::modular::StoryActivityWatcher|
  void OnStoryActivityChange(
      fidl::StringPtr story_id,
      fidl::VectorPtr<fuchsia::modular::OngoingActivityType> activities)
      override {
    on_notify_(std::move(story_id), std::move(activities));
  }

  fidl::Binding<fuchsia::modular::StoryActivityWatcher> binding_;
  std::function<void(fidl::StringPtr,
                     fidl::VectorPtr<fuchsia::modular::OngoingActivityType>)>
      on_notify_;

  FXL_DISALLOW_COPY_AND_ASSIGN(StoryActivityWatcherImpl);
};

class TestApp : public modular::testing::SessionShellBase {
 public:
  TestApp(component::StartupContext* const startup_context)
      : SessionShellBase(startup_context), weak_ptr_factory_(this) {
    TestInit(__FILE__);

    startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());

    CreateStory();
  }

  ~TestApp() override = default;

 private:
  TestPoint story_create_{"Created story."};
  void CreateStory() {
    fidl::VectorPtr<fuchsia::modular::StoryCommand> commands;
    {
      fuchsia::modular::AddMod add_mod;
      add_mod.mod_name.push_back(kFirstModuleName);
      add_mod.intent = IntentWithParameterString(kFirstModuleName);

      fuchsia::modular::StoryCommand command;
      command.set_add_mod(std::move(add_mod));
      commands.push_back(std::move(command));
    }
    {
      fuchsia::modular::AddMod add_mod;
      add_mod.mod_name.push_back(kSecondModuleName);
      add_mod.intent = IntentWithParameterString(kSecondModuleName);

      fuchsia::modular::StoryCommand command;
      command.set_add_mod(std::move(add_mod));
      commands.push_back(std::move(command));
    }
    {
      fuchsia::modular::Intent intent;
      intent.handler = "module_context_test_entity_module";
      intent.action = "test";
      fuchsia::modular::AddMod add_mod;
      add_mod.mod_name.push_back("entity_module");
      add_mod.intent = std::move(intent);
      add_mod.surface_parent_mod_name.resize(0);

      fuchsia::modular::StoryCommand command;
      command.set_add_mod(std::move(add_mod));
      commands.push_back(std::move(command));
    }

    puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
    story_puppet_master_->Enqueue(std::move(commands));
    story_puppet_master_->Execute(
        [this](fuchsia::modular::ExecuteResult result) {
          story_create_.Pass();
          StartStory();
        });
  }

  TestPoint story_get_controller_{"Story GetController()"};
  // Starts the story and adds two modules to it.
  void StartStory() {
    story_provider()->GetController(kStoryName, story_controller_.NewRequest());
    story_controller_.set_error_handler([this](zx_status_t status) {
      FXL_LOG(ERROR) << "Story controller for story " << kStoryName
                     << " died. Does this story exist?";
    });

    story_controller_->RequestStart();
    story_controller_->GetInfo(
        [this](fuchsia::modular::StoryInfo, fuchsia::modular::StoryState) {
          story_get_controller_.Pass();
          PerformWatchActivity();
        });
  }

  TestPoint on_watch_ongoing_activities_dispatched{
      "When a watcher is registered, ongoing activities should be dispatched."};
  void PerformWatchActivity() {
    story_activity_watcher_.Watch(story_provider());
    story_activity_watcher_.OnNotify(
        [this](
            fidl::StringPtr story_id,
            fidl::VectorPtr<fuchsia::modular::OngoingActivityType> activities) {
          if (story_id == kStoryName && activities->empty()) {
            on_watch_ongoing_activities_dispatched.Pass();
          }
          PerformFirstModuleStartActivity();
        });
  }

  TestPoint on_start_ongoing_activity_dispatched{
      "When there is a new ongoing activity, the ongoing activity should be "
      "dispatched."};
  // Signals the first module to call ModuleContext.StartOngoingActivity().
  void PerformFirstModuleStartActivity() {
    Signal(kFirstModuleCallStartActivity);
    story_activity_watcher_.OnNotify(
        [this](
            fidl::StringPtr story_id,
            fidl::VectorPtr<fuchsia::modular::OngoingActivityType> activities) {
          if (story_id == kStoryName && activities->size() == 1 &&
              activities.get()[0] ==
                  fuchsia::modular::OngoingActivityType::VIDEO) {
            on_start_ongoing_activity_dispatched.Pass();
          }
          PerformSecondModuleStartActivity();
        });
  }

  TestPoint on_start_all_ongoing_activities_dispatched{
      "When there is a new ongoing activity, all ongoing activities should be "
      "dispatched."};
  // Signals the second module to call ModuleContext.StartOngoingActivity().
  void PerformSecondModuleStartActivity() {
    Signal(kSecondModuleCallStartActivity);
    story_activity_watcher_.OnNotify(
        [this](
            fidl::StringPtr story_id,
            fidl::VectorPtr<fuchsia::modular::OngoingActivityType> activities) {
          if (story_id == kStoryName && activities->size() == 2 &&
              activities.get()[0] ==
                  fuchsia::modular::OngoingActivityType::VIDEO &&
              activities.get()[1] ==
                  fuchsia::modular::OngoingActivityType::VIDEO) {
            on_start_all_ongoing_activities_dispatched.Pass();
          }
          PerformSecondModuleStopActivity();
        });
  }

  TestPoint on_stop_remaining_ongoing_activities_dispatched{
      "When an ongoing activity is stopped, all remaining ongoing activities "
      "should be dispatched."};
  // Signals the second module to stop ongoing activity.
  void PerformSecondModuleStopActivity() {
    Signal(kSecondModuleCallStopActivity);
    story_activity_watcher_.OnNotify(
        [this](
            fidl::StringPtr story_id,
            fidl::VectorPtr<fuchsia::modular::OngoingActivityType> activities) {
          if (story_id == kStoryName && activities->size() == 1 &&
              activities.get()[0] ==
                  fuchsia::modular::OngoingActivityType::VIDEO) {
            on_stop_remaining_ongoing_activities_dispatched.Pass();
          }
          TestModuleCreatingEntity();
        });
  }

  void TestModuleCreatingEntity() {
    Await(kEntityModuleDoneFirstTask, [this] {
      Await(kEntityModuleDoneSecondTask, [this] {
        fuchsia::modular::Intent intent;
        intent.handler = "module_context_test_entity_module";
        intent.action = "test";
        fuchsia::modular::RemoveMod remove_mod;
        remove_mod.mod_name.push_back("entity_module");

        fidl::VectorPtr<fuchsia::modular::StoryCommand> commands;
        fuchsia::modular::StoryCommand command;
        command.set_remove_mod(std::move(remove_mod));
        commands.push_back(std::move(command));

        puppet_master_->ControlStory(kStoryName,
                                     story_puppet_master_.NewRequest());
        story_puppet_master_->Enqueue(std::move(commands));
        story_puppet_master_->Execute(
            [this](fuchsia::modular::ExecuteResult result) {
              PerformFirstModuleDone();
            });
      });
    });
  }

  TestPoint on_done_ongoing_activities_stopped{
      "When a module is teared down, the ongoing activity should also be "
      "stopped"};
  TestPoint second_module_active_{
      "Only second module is still active after first calls "
      "RemoveSelfFromStory()"};
  // Signals the first module to call ModuleContext.RemoveSelfFromStory().
  void PerformFirstModuleDone() {
    Signal(kFirstModuleCallDone);
    Await(kFirstModuleTerminated, [this] {
      // Verify that the second module is still active, but the first one is
      // not.
      story_controller_->GetActiveModules(
          nullptr,
          [this](fidl::VectorPtr<fuchsia::modular::ModuleData> module_data) {
            if (module_data->size() == 1) {
              second_module_active_.Pass();
            }
            VerifyStoryStillRunning();
          });
    });

    story_activity_watcher_.OnNotify(
        [this](
            fidl::StringPtr story_id,
            fidl::VectorPtr<fuchsia::modular::OngoingActivityType> activities) {
          if (story_id == kStoryName && activities->empty()) {
            on_done_ongoing_activities_stopped.Pass();
          }
        });
  }

  TestPoint story_still_active_{
      "The story is still active after first module calls "
      "RemoveSelfFromStory()"};
  // Verifies that the story is still running after the first module has called
  // done and been stopped.
  void VerifyStoryStillRunning() {
    IsStoryRunning([this](bool is_running) {
      if (is_running) {
        story_still_active_.Pass();
      }
      PerformSecondModuleDone();
    });
  }

  TestPoint no_module_active_{
      "No modules are active after second mod calls RemoveSelfFromStory()"};
  TestPoint story_stopped_{"The story was stopped."};
  // Signals the second module to call ModuleContext.Done.
  void PerformSecondModuleDone() {
    Signal(kSecondModuleCallDone);
    Await(kSecondModuleTerminated, [this] {
      // Verify that the second module is still active.
      story_controller_->GetActiveModules(
          nullptr,
          [this](fidl::VectorPtr<fuchsia::modular::ModuleData> module_data) {
            if (module_data->empty()) {
              no_module_active_.Pass();
            }
            IsStoryRunning([this](bool is_running) {
              if (!is_running) {
                story_stopped_.Pass();
              }

              Signal(modular::testing::kTestShutdown);
            });
          });
    });
  }

  // Verifies that the story is stopped when the last module that is part of the
  // story calls ModuleContext.Done and is stopped.
  void IsStoryRunning(std::function<void(bool)> callback) {
    story_provider()->RunningStories(
        [this, callback](fidl::VectorPtr<fidl::StringPtr> story_ids) {
          bool found_story = false;
          // Check all the running stories to make sure the one created for this
          // test is no longer running.
          for (const auto& story_id : *story_ids) {
            found_story |= story_id == kStoryName;
          }
          callback(found_story);
        });
  }

  // Creates an intent with one parameter, kLinkName, with the following
  // contents: { |kLinkKey| : |parameter_string| }.
  fuchsia::modular::Intent IntentWithParameterString(
      std::string parameter_string) {
    fuchsia::modular::Intent intent;
    intent.handler = kModuleUrl;
    intent.action = kIntentAction;

    fuchsia::modular::IntentParameter parameter;
    parameter.name = kLinkName;

    rapidjson::Document document;
    document.SetObject();
    document.AddMember(kLinkKey, parameter_string, document.GetAllocator());

    fuchsia::modular::IntentParameterData parameter_data;
    fsl::SizedVmo vmo;
    FXL_CHECK(fsl::VmoFromString(modular::JsonValueToString(document), &vmo));
    parameter_data.set_json(std::move(vmo).ToTransport());
    parameter.data = std::move(parameter_data);
    intent.parameters.push_back(std::move(parameter));

    return intent;
  }

  fuchsia::modular::PuppetMasterPtr puppet_master_;
  fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
  fuchsia::modular::StoryControllerPtr story_controller_;
  StoryActivityWatcherImpl story_activity_watcher_;

  fxl::WeakPtrFactory<TestApp> weak_ptr_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
};

}  // namespace

int main(int /*argc*/, const char** /*argv*/) {
  modular::testing::ComponentMain<TestApp>();
  return 0;
}
