// 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 "peridot/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h"

#include <lib/fsl/vmo/strings.h>

#include "gtest/gtest.h"
#include "peridot/lib/testing/test_with_session_storage.h"

namespace modular {
namespace {

class SetKindOfProtoStoryOptionCommandRunnerTest
    : public testing::TestWithSessionStorage {
 public:
  void SetUp() override {
    testing::TestWithSessionStorage::SetUp();
    session_storage_ = MakeSessionStorage("page");
    runner_ = MakeRunner();
    story_id_ = CreateStory(session_storage_.get());
  }

 protected:
  std::unique_ptr<SetKindOfProtoStoryOptionCommandRunner> MakeRunner() {
    return std::make_unique<SetKindOfProtoStoryOptionCommandRunner>(
        session_storage_.get());
  }

  std::unique_ptr<SessionStorage> session_storage_;
  std::unique_ptr<SetKindOfProtoStoryOptionCommandRunner> runner_;
  std::string story_id_;
};

TEST_F(SetKindOfProtoStoryOptionCommandRunnerTest, Execute) {
  fuchsia::modular::StoryCommand command;
  fuchsia::modular::SetKindOfProtoStoryOption set_kind_of_proto_story_option;
  bool done{};

  // Set a value.
  {
    set_kind_of_proto_story_option.value = true;
    command.set_set_kind_of_proto_story_option(
        std::move(set_kind_of_proto_story_option));
    runner_->Execute(story_id_, nullptr /* story_storage */, std::move(command),
                     [&](fuchsia::modular::ExecuteResult result) {
                       EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
                                 result.status);
                       done = true;
                     });
    RunLoopUntil([&] { return done; });
  }

  // Verify it was written.
  done = false;
  session_storage_->GetStoryData(story_id_)->Then(
      [&](fuchsia::modular::internal::StoryDataPtr data) {
        EXPECT_TRUE(data->story_options().kind_of_proto_story);
        done = true;
      });
  RunLoopUntil([&] { return done; });

  // Update the value.
  {
    set_kind_of_proto_story_option.value = false;
    command.set_set_kind_of_proto_story_option(
        std::move(set_kind_of_proto_story_option));
    done = false;
    runner_->Execute(story_id_, nullptr /* story_storage */, std::move(command),
                     [&](fuchsia::modular::ExecuteResult result) {
                       EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
                                 result.status);
                       done = true;
                     });
    RunLoopUntil([&] { return done; });
  }

  // Verify second value.
  done = false;
  session_storage_->GetStoryData(story_id_)->Then(
      [&](fuchsia::modular::internal::StoryDataPtr data) {
        EXPECT_FALSE(data->story_options().kind_of_proto_story);
        done = true;
      });
  RunLoopUntil([&] { return done; });
}

}  // namespace
}  // namespace modular
