// 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 <lib/fit/bridge.h>
#include <lib/fit/function.h>
#include <lib/fit/single_threaded_executor.h>

#include "lib/gtest/test_loop_fixture.h"
#include "peridot/bin/sessionmgr/story/model/story_model_owner.h"
#include "peridot/bin/sessionmgr/story/model/story_model_storage.h"

using fuchsia::modular::StoryVisibilityState;
using fuchsia::modular::storymodel::StoryModel;
using fuchsia::modular::storymodel::StoryModelMutation;

namespace modular {
namespace {

// This persistence system acts as a mock for calls to Execute(), and promotes
// Observe() from protected to public so that we can call it directly from the
// test body.
class TestModelStorage : public StoryModelStorage {
 public:
  struct ExecuteCall {
    std::vector<StoryModelMutation> commands;

    // Call this after a call to Execute() to complete the returned promise.
    fit::completer<> completer;
  };
  std::vector<ExecuteCall> calls;

  fit::promise<> Load() override {
    return fit::make_promise([] { return fit::ok(); });
  }

  fit::promise<> Flush() override {
    return fit::make_promise([] { return fit::ok(); });
  }

  fit::promise<> Execute(std::vector<StoryModelMutation> commands) override {
    fit::bridge<> bridge;

    // Store the arguments we got.
    ExecuteCall call{.commands = std::move(commands),
                     .completer = std::move(bridge.completer)};
    calls.push_back(std::move(call));

    return bridge.consumer.promise();
  }

  using StoryModelStorage::Observe;
};

class StoryModelOwnerTest : public ::gtest::TestLoopFixture {
 public:
  StoryModelOwnerTest() : TestLoopFixture() { ResetExecutor(); }

  std::unique_ptr<StoryModelOwner> Create(const std::string& story_name) {
    auto model_storage = std::make_unique<TestModelStorage>();
    model_storage_ = model_storage.get();

    auto owner = std::make_unique<StoryModelOwner>(story_name, executor_.get(),
                                                   std::move(model_storage));
    return owner;
  }

  void ResetExecutor() { executor_.reset(new async::Executor(dispatcher())); }

  TestModelStorage* model_storage() { return model_storage_; }

 private:
  std::unique_ptr<async::Executor> executor_;
  TestModelStorage* model_storage_;
};

TEST_F(StoryModelOwnerTest, SuccessfulMutate) {
  // Show that a single mutation flows through the StoryModelOwner to
  // StoryModelStorage, and then applies the resulting commands.
  auto owner = Create("test_name");

  auto mutator = owner->NewMutator();
  bool done{false};
  auto result_task =
      mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
          .promise()
          .and_then([&] { done = true; })
          .or_else([] { FAIL(); });
  RunLoopUntilIdle();

  // The persistence system should have been called.
  ASSERT_EQ(1lu, model_storage()->calls.size());
  ASSERT_EQ(1lu, model_storage()->calls[0].commands.size());
  EXPECT_TRUE(model_storage()->calls[0].commands[0].is_set_visibility_state());
  EXPECT_EQ(StoryVisibilityState::IMMERSIVE,
            model_storage()->calls[0].commands[0].set_visibility_state());

  // Complete the pending persistence call.
  model_storage()->calls[0].completer.complete_ok();
  RunLoopUntilIdle();
  fit::run_single_threaded(std::move(result_task));
  EXPECT_TRUE(done);

  // The existing model hasn't changed, because the StoryModelStorage
  // has not heard back from its storage that the mutation occurred.
  auto observer = owner->NewObserver();
  EXPECT_EQ("test_name", *observer->model().name());
  EXPECT_EQ(StoryVisibilityState::DEFAULT,
            *observer->model().visibility_state());

  // Now dispatch mutations from the persistence system, and we should observe
  // that ApplyMutations() is invoked.
  model_storage()->Observe(std::move(model_storage()->calls[0].commands));

  // And the new model value that ApplyMutations returned should be reflected in
  // the owner.
  EXPECT_EQ(StoryVisibilityState::IMMERSIVE,
            *observer->model().visibility_state());
}

TEST_F(StoryModelOwnerTest, FailedMutate) {
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  bool task_executed{false};
  bool saw_error{false};
  auto result_task =
      mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
          .promise()
          .and_then([&] { task_executed = true; })
          .or_else([&] { saw_error = true; });
  RunLoopUntilIdle();
  model_storage()->calls[0].completer.complete_error();
  RunLoopUntilIdle();
  fit::run_single_threaded(std::move(result_task));
  EXPECT_FALSE(task_executed);
  EXPECT_TRUE(saw_error);
}

TEST_F(StoryModelOwnerTest, AbandonedMutate) {
  // If for some reason the underlying mutation is abandoned, we should observe
  // an error.
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  bool task_executed{false};
  bool saw_error{false};
  auto result_task =
      mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
          .promise_or(fit::error())  // turn abandonment into an error.
          .and_then([&] { task_executed = true; })
          .or_else([&] { saw_error = true; });
  RunLoopUntilIdle();
  // Clearing the list of calls will destroy the completer, which has the
  // side-effect of abandoning the returned task.
  model_storage()->calls.clear();
  RunLoopUntilIdle();
  fit::run_single_threaded(std::move(result_task));
  EXPECT_FALSE(task_executed);
  EXPECT_TRUE(saw_error);
}

TEST_F(StoryModelOwnerTest, MutatorLifecycle_OwnerDestroyed) {
  // When the StoryModelOwner is destroyed but someone is still holding onto a
  // StoryMutator that mutator should return an error on Execute().
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  owner.reset();
  bool task_executed{false};
  bool saw_error{false};
  auto result_task =
      mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
          .promise()
          .and_then([&] { task_executed = true; })
          .or_else([&] { saw_error = true; });
  RunLoopUntilIdle();
  fit::run_single_threaded(std::move(result_task));
  EXPECT_FALSE(task_executed);
  EXPECT_TRUE(saw_error);
}

TEST_F(StoryModelOwnerTest, ObserversAreNotified) {
  // One can create an observer and learn of the new state.
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  auto observer = owner->NewObserver();

  bool got_update1{false};
  observer->RegisterListener([&](const StoryModel& model) {
    got_update1 = true;
    EXPECT_EQ(StoryVisibilityState::IMMERSIVE, *model.visibility_state());
  });

  // Another listener should also get the update!
  bool got_update2{false};
  observer->RegisterListener(
      [&](const StoryModel& model) { got_update2 = true; });

  // Also on another observer.
  auto observer2 = owner->NewObserver();
  bool got_update3{false};
  observer2->RegisterListener(
      [&](const StoryModel& model) { got_update3 = true; });

  std::vector<StoryModelMutation> commands;
  commands.resize(1);
  commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
  model_storage()->Observe(std::move(commands));
  RunLoopUntilIdle();
  EXPECT_TRUE(got_update1);
  EXPECT_TRUE(got_update2);
  EXPECT_TRUE(got_update3);
}

TEST_F(StoryModelOwnerTest, ObserversAreNotNotifiedOnNoChange) {
  // Observers aren't told when an observed mutation doesn't change the model.
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  auto observer = owner->NewObserver();

  bool got_update{false};
  observer->RegisterListener([&](const StoryModel& model) {
    got_update = true;
  });

  std::vector<StoryModelMutation> commands;
  commands.resize(1);
  commands[0].set_set_visibility_state(StoryVisibilityState::DEFAULT);
  model_storage()->Observe(std::move(commands));
  RunLoopUntilIdle();
  EXPECT_FALSE(got_update);
}

TEST_F(StoryModelOwnerTest, ObserversLifecycle_ClientDestroyed) {
  // When the client destroys its observer object, it no longer receives
  // updates.
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  auto observer = owner->NewObserver();

  bool got_update{false};
  observer->RegisterListener(
      [&](const StoryModel& model) { got_update = true; });

  std::vector<StoryModelMutation> commands;
  commands.resize(1);
  commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
  model_storage()->Observe(std::move(commands));

  observer.reset();
  RunLoopUntilIdle();
  EXPECT_FALSE(got_update);
}

TEST_F(StoryModelOwnerTest, ObserversLifecycle_OwnerDestroyed) {
  // When the StoryModelOwner is destroyed, clients can learn of the fact by
  // using a fit::defer on the listener callback.
  auto owner = Create("test");
  auto mutator = owner->NewMutator();
  auto observer = owner->NewObserver();

  bool destroyed{false};
  observer->RegisterListener([defer = fit::defer([&] { destroyed = true; })](
                                 const StoryModel& model) {});

  owner.reset();
  EXPECT_TRUE(destroyed);

  // Explicitly destroy |observer| to ensure that its cleanup isn't affected by
  // |owner| being destroyed.
  observer.reset();
}

}  // namespace
}  // namespace modular
