// Copyright 2019 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 <fuchsia/modular/testing/cpp/fidl.h>

#include <gmock/gmock.h>

#include "lib/syslog/cpp/macros.h"
#include "src/lib/fsl/vmo/strings.h"
#include "src/modular/lib/modular_test_harness/cpp/fake_module.h"
#include "src/modular/lib/modular_test_harness/cpp/fake_session_shell.h"
#include "src/modular/lib/modular_test_harness/cpp/test_harness_fixture.h"

using testing::ElementsAre;

namespace {

class ModuleContextTest : public modular_testing::TestHarnessFixture {
 protected:
  ModuleContextTest()
      : session_shell_(modular_testing::FakeSessionShell::CreateWithDefaultOptions()) {}

  void StartSession(modular_testing::TestHarnessBuilder builder) {
    builder.InterceptSessionShell(session_shell_->BuildInterceptOptions());
    builder.BuildAndRun(test_harness());

    // Wait for our session shell to start.
    RunLoopUntil([this] { return session_shell_->is_running(); });
  }

  void RestartStory(std::string story_name) {
    fuchsia::modular::StoryControllerPtr story_controller;
    session_shell_->story_provider()->GetController(story_name, story_controller.NewRequest());

    bool restarted = false;
    story_controller->Stop([&] {
      story_controller->RequestStart();
      restarted = true;
    });
    RunLoopUntil([&] { return restarted; });
  }

  std::unique_ptr<modular_testing::FakeSessionShell> session_shell_;
};

// A version of FakeModule which captures handled intents in a std::vector<>
// and exposes callbacks triggered on certain lifecycle events.
class TestModule : public modular_testing::FakeModule {
 public:
  explicit TestModule(std::string module_name = "")
      : modular_testing::FakeModule(
            {.url = modular_testing::TestHarnessBuilder::GenerateFakeUrl(module_name),
             .sandbox_services = modular_testing::FakeModule::GetDefaultSandboxServices()}) {}
  fit::function<void()> on_destroy;
  fit::function<void()> on_create;
  fuchsia::modular::ModuleControllerPtr controller;

 private:
  // |modular_testing::FakeModule|
  void OnCreate(fuchsia::sys::StartupInfo startup_info) override {
    modular_testing::FakeModule::OnCreate(std::move(startup_info));
    if (on_create)
      on_create();
  }

  // |modular_testing::FakeModule|
  void OnDestroy() override {
    if (on_destroy)
      on_destroy();
  }
};

class TestStoryWatcher : fuchsia::modular::StoryWatcher {
 public:
  TestStoryWatcher(fit::function<void(fuchsia::modular::StoryState)> on_state_change)
      : binding_(this), on_state_change_(std::move(on_state_change)) {}
  ~TestStoryWatcher() override = default;

  // Registers itself as a watcher on the given story. Only one story at a time
  // can be watched.
  void Watch(fuchsia::modular::StoryController* const story_controller) {
    story_controller->Watch(binding_.NewBinding());
  }

 private:
  // |fuchsia::modular::StoryWatcher|
  void OnStateChange(fuchsia::modular::StoryState state) override { on_state_change_(state); }
  void OnModuleAdded(fuchsia::modular::ModuleData /*module_data*/) override {}
  void OnModuleFocused(std::vector<std::string> /*module_path*/) override {}

  fidl::Binding<fuchsia::modular::StoryWatcher> binding_;
  fit::function<void(fuchsia::modular::StoryState)> on_state_change_;
};

// Test that ModuleContext.RemoveSelfFromStory() on the only mod in a story has
// the affect of shutting down the module and removing it permanently from the
// story (if the story is restarted, it is not relaunched).
TEST_F(ModuleContextTest, RemoveSelfFromStory) {
  TestModule module1("module1");

  modular_testing::TestHarnessBuilder builder;
  builder.InterceptComponent(module1.BuildInterceptOptions());

  StartSession(std::move(builder));
  modular_testing::AddModToStory(test_harness(), "storyname", "modname1",
                                 {.action = "action", .handler = module1.url()});
  RunLoopUntil([&] { return module1.is_running(); });

  // Instruct module1 to remove itself from the story. Expect to see that
  // module1 is terminated.
  module1.module_context()->RemoveSelfFromStory();
  RunLoopUntil([&] { return !module1.is_running(); });

  // Additionally, restarting the story should not result in module1 being
  // restarted.
  fuchsia::modular::StoryControllerPtr story_controller;
  session_shell_->story_provider()->GetController("storyname", story_controller.NewRequest());
  bool story_stopped = false;
  bool story_restarted = false;
  TestStoryWatcher story_watcher([&](fuchsia::modular::StoryState state) {
    if (state == fuchsia::modular::StoryState::STOPPED) {
      story_stopped = true;
    } else if (state == fuchsia::modular::StoryState::RUNNING) {
      story_restarted = true;
    }
  });
  story_watcher.Watch(story_controller.get());
  RestartStory("storyname");
  RunLoopUntil([&] { return story_stopped && story_restarted; });
  EXPECT_FALSE(module1.is_running());
}

// Test that when ModuleContext.RemoveSelfFromStory() is called on one of two
// modules in a story, it has the affect of shutting down the module and
// removing it permanently from the story (if the story is restarted, it is not
// relaunched).
TEST_F(ModuleContextTest, RemoveSelfFromStory_2mods) {
  modular_testing::TestHarnessBuilder builder;

  TestModule module1("module1");
  TestModule module2("module2");
  builder.InterceptComponent(module1.BuildInterceptOptions());
  builder.InterceptComponent(module2.BuildInterceptOptions());

  StartSession(std::move(builder));
  modular_testing::AddModToStory(test_harness(), "storyname", "modname1",
                                 {.action = "action", .handler = module1.url()});
  modular_testing::AddModToStory(test_harness(), "storyname", "modname2",
                                 {.action = "action", .handler = module2.url()});
  RunLoopUntil([&] { return module1.is_running() && module2.is_running(); });

  // Instruct module1 to remove itself from the story. Expect to see that
  // module1 is terminated and module2 is not.
  module1.module_context()->RemoveSelfFromStory();
  RunLoopUntil([&] { return !module1.is_running(); });
  ASSERT_TRUE(module2.is_running());

  // Additionally, restarting the story should not result in module1 being
  // restarted whereas it should for module2.
  bool module2_destroyed = false;
  bool module2_restarted = false;
  module2.on_destroy = [&] { module2_destroyed = true; };
  module2.on_create = [&] { module2_restarted = true; };
  RestartStory("storyname");
  RunLoopUntil([&] { return module2_restarted; });
  EXPECT_FALSE(module1.is_running());
  EXPECT_TRUE(module2_destroyed);
}

}  // namespace
