// Copyright 2017 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/context_engine/context_repository.h"

#include <fuchsia/modular/cpp/fidl.h>
#include <lib/context/cpp/context_helper.h>
#include <lib/context/cpp/context_metadata_builder.h>
#include <lib/fidl/cpp/clone.h>
#include <lib/fidl/cpp/optional.h>

#include "gtest/gtest.h"

using maxwell::ContextMetadataBuilder;

namespace modular {
namespace {

TEST(ContextGraph, GetChildrenRecursive_GetAncestors) {
  ContextGraph graph;

  graph.AddEdge("a", "b");
  graph.AddEdge("b", "c");
  graph.AddEdge("b", "d");

  auto children = graph.GetChildrenRecursive("b");
  EXPECT_EQ(2lu, children.size());
  EXPECT_TRUE(children.find("c") != children.end());
  EXPECT_TRUE(children.find("d") != children.end());

  children = graph.GetChildrenRecursive("a");
  EXPECT_EQ(3lu, children.size());
  EXPECT_TRUE(children.find("b") != children.end());
  EXPECT_TRUE(children.find("c") != children.end());
  EXPECT_TRUE(children.find("d") != children.end());

  auto ancestors = graph.GetAncestors("c");
  EXPECT_EQ(2lu, ancestors.size());
  EXPECT_EQ("a", ancestors[0]);
  EXPECT_EQ("b", ancestors[1]);
}

class ContextRepositoryTest : public ::testing::Test {
 public:
  ContextRepositoryTest() {}

 protected:
  ContextRepository repository_;
};

class TestListener : public fuchsia::modular::ContextListener {
 public:
  fuchsia::modular::ContextUpdatePtr last_update;

  void OnContextUpdate(fuchsia::modular::ContextUpdate update) override {
    last_update = fidl::MakeOptional(std::move(update));
  }

  void reset() { last_update.reset(); }
};

fuchsia::modular::ContextValue CreateValue(fuchsia::modular::ContextValueType type,
                                           const std::string& content) {
  fuchsia::modular::ContextValue value;
  value.type = type;
  value.content = content;
  return value;
}

fuchsia::modular::ContextValue CreateValue(fuchsia::modular::ContextValueType type,
                                           const std::string& content,
                                           fuchsia::modular::ContextMetadata meta) {
  fuchsia::modular::ContextValue value;
  value.type = type;
  value.content = content;
  value.meta = std::move(meta);
  return value;
}

}  // namespace

TEST_F(ContextRepositoryTest, GetAddUpdateRemove) {
  // This test ensures that we can do basic, synchronous add/update/remove/get
  // operations.

  // Show that when we set values, we can get them back.
  auto id1 = repository_.Add(CreateValue(fuchsia::modular::ContextValueType::ENTITY, "content"));
  auto value1 = repository_.Get(id1);
  ASSERT_TRUE(value1);
  EXPECT_EQ(fuchsia::modular::ContextValueType::ENTITY, value1->type);
  EXPECT_EQ("content", value1->content);

  // Setting another value doesn't affect the original value.
  auto id2 = repository_.Add(CreateValue(fuchsia::modular::ContextValueType::ENTITY, "content2"));
  auto value2 = repository_.Get(id2);
  ASSERT_TRUE(value2);
  EXPECT_EQ("content2", value2->content);
  value1 = repository_.Get(id1);
  ASSERT_TRUE(value1);
  EXPECT_EQ(fuchsia::modular::ContextValueType::ENTITY, value1->type);
  EXPECT_EQ("content", value1->content);

  // Let's create metadata.
  auto id3 = repository_.Add(CreateValue(fuchsia::modular::ContextValueType::ENTITY, "content3",
                                         ContextMetadataBuilder().SetStoryId("id3story").Build()));
  auto value3 = repository_.Get(id3);
  ASSERT_TRUE(value3);
  EXPECT_EQ("content3", value3->content);
  ASSERT_TRUE(value3->meta.story);
  EXPECT_EQ("id3story", value3->meta.story->id);

  // Update one of the previous values.
  repository_.Update(id2, CreateValue(fuchsia::modular::ContextValueType::ENTITY, "new content2",
                                      ContextMetadataBuilder().SetStoryId("id2story").Build()));
  value2 = repository_.Get(id2);
  ASSERT_TRUE(value2);
  ASSERT_TRUE(value2->meta.story);
  EXPECT_EQ("id2story", value2->meta.story->id);
  EXPECT_EQ("new content2", value2->content);

  // Now remove id3.
  repository_.Remove(id3);
  EXPECT_FALSE(repository_.Get(id3));
  EXPECT_TRUE(repository_.Get(id1));
  EXPECT_TRUE(repository_.Get(id2));

  // And the others.
  repository_.Remove(id1);
  repository_.Remove(id2);
  EXPECT_FALSE(repository_.Get(id1));
  EXPECT_FALSE(repository_.Get(id2));
}

TEST_F(ContextRepositoryTest, ValuesInheritMetadata) {
  // When a value is added as a child of another value, the child inherits the
  // metadata of its parent.
  auto meta1 = ContextMetadataBuilder().SetStoryId("id").Build();
  auto id1 = repository_.Add(
      CreateValue(fuchsia::modular::ContextValueType::STORY, "s", std::move(meta1)));

  auto meta2 = ContextMetadataBuilder().SetModuleUrl("url").Build();
  auto id2 = repository_.Add(
      id1, CreateValue(fuchsia::modular::ContextValueType::MODULE, "m", std::move(meta2)));

  auto value1 = repository_.GetMerged(id1);
  ASSERT_TRUE(value1);
  // value1's metadata shouldn't have changed.
  ASSERT_TRUE(value1->meta.story);
  EXPECT_EQ("id", value1->meta.story->id);
  ASSERT_FALSE(value1->meta.mod);

  auto value2 = repository_.GetMerged(id2);
  ASSERT_TRUE(value2);
  // value2's metadata should combine both value1's and value2's.
  ASSERT_TRUE(value2->meta.story);
  EXPECT_EQ("id", value2->meta.story->id);
  ASSERT_TRUE(value2->meta.mod);
  ASSERT_TRUE(value2->meta.mod->url);
  EXPECT_EQ("url", value2->meta.mod->url);

  // Changing the parent's metadata value should update the child's also.
  meta1 = fuchsia::modular::ContextMetadata();
  meta1.story = fuchsia::modular::StoryMetadata::New();
  meta1.story->id = "newid";
  repository_.Update(id1,
                     CreateValue(fuchsia::modular::ContextValueType::STORY, "s", std::move(meta1)));
  value2 = repository_.GetMerged(id2);
  ASSERT_TRUE(value2);
  ASSERT_TRUE(value2->meta.story);
  EXPECT_EQ("newid", value2->meta.story->id);
  ASSERT_TRUE(value2->meta.mod);
  ASSERT_TRUE(value2->meta.mod->url);
  EXPECT_EQ("url", value2->meta.mod->url);

  // If a parent contains metadata that the child also contains (they both have
  // 'mod' metadata), the parent's takes precendence.
  meta1 = ContextMetadataBuilder(std::move(meta1)).SetModuleUrl("override").Build();
  repository_.Update(id1,
                     CreateValue(fuchsia::modular::ContextValueType::STORY, "s", std::move(meta1)));
  value2 = repository_.GetMerged(id2);
  ASSERT_TRUE(value2);
  ASSERT_FALSE(value2->meta.story);
  ASSERT_TRUE(value2->meta.mod);
  ASSERT_EQ("override", value2->meta.mod->url);
}

TEST_F(ContextRepositoryTest, ListenersGetUpdates) {
  // We want to test these subscription behaviors.
  // 1) A value is added but doesn't match our subscription.
  //    a) It's the wrong type (ie, STORY vs ENTITY)
  //    b) Its metadata doesn't match.
  // 2) A value is added that matches our existing subscription.
  // 3) A value is updated that newly matches our subscription.
  // 4) When a value is removed, it is no longer returned.

  // (1)
  fuchsia::modular::ContextQuery query;
  fuchsia::modular::ContextSelector selector;
  selector.type = fuchsia::modular::ContextValueType::ENTITY;
  selector.meta = ContextMetadataBuilder().SetEntityTopic("topic").BuildPtr();
  AddToContextQuery(&query, "a", std::move(selector));

  TestListener listener;
  repository_.AddSubscription(std::move(query), &listener,
                              fuchsia::modular::SubscriptionDebugInfo());
  auto maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  EXPECT_TRUE(maybe_result.value().empty());
  listener.reset();

  // (a)
  fuchsia::modular::ContextValue value;
  value.type = fuchsia::modular::ContextValueType::STORY;
  value.content = "no match";
  value.meta = ContextMetadataBuilder().SetEntityTopic("topic").Build();
  repository_.Add(std::move(value));
  // No new update because nothing changed for our subscription.
  EXPECT_FALSE(listener.last_update);
  listener.reset();

  // (b)
  value = fuchsia::modular::ContextValue();
  value.type = fuchsia::modular::ContextValueType::ENTITY;
  value.content = "no match yet";
  value.meta = ContextMetadataBuilder().SetEntityTopic("not the topic").Build();
  auto id = repository_.Add(std::move(value));  // Save id for later.
  // No new update because nothing changed for our subscription.
  EXPECT_FALSE(listener.last_update);
  listener.reset();

  // (2)
  value = fuchsia::modular::ContextValue();
  value.type = fuchsia::modular::ContextValueType::ENTITY;
  value.content = "match";
  value.meta = ContextMetadataBuilder().SetEntityTopic("topic").Build();
  repository_.Add(std::move(value));
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  {
    auto& result = maybe_result.value();
    EXPECT_EQ(1lu, result.size());
    EXPECT_EQ("match", result.at(0).content);
  }
  listener.reset();

  // (3)
  value = fuchsia::modular::ContextValue();
  value.type = fuchsia::modular::ContextValueType::ENTITY;
  value.content = "now it matches";
  // Add more metadata than the query is looking for. It shouldn't affect
  // the query, because it doesn't express any constraint on 'type'.
  value.meta = ContextMetadataBuilder()
                   .SetEntityTopic("topic")
                   .AddEntityType("type1")
                   .AddEntityType("type2")
                   .Build();
  repository_.Update(id, std::move(value));
  ASSERT_TRUE(listener.last_update);
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  {
    auto& result = maybe_result.value();
    EXPECT_EQ(2lu, result.size());
    EXPECT_EQ("now it matches", result.at(0).content);
    EXPECT_EQ("match", result.at(1).content);
  }
  listener.reset();

  // (4)
  repository_.Remove(id);
  ASSERT_TRUE(listener.last_update);
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  {
    auto& result = maybe_result.value();
    EXPECT_EQ(1lu, result.size());
    EXPECT_EQ("match", result.at(0).content);
  }
  listener.reset();
}

TEST_F(ContextRepositoryTest, ListenersGetUpdates_WhenParentsUpdated) {
  // We should see updates to listeners when an update to a node's
  // parent causes that node to be matched by a query.
  fuchsia::modular::ContextQuery query;
  fuchsia::modular::ContextSelector selector;
  selector.type = fuchsia::modular::ContextValueType::ENTITY;
  selector.meta = ContextMetadataBuilder().SetStoryId("match").BuildPtr();
  AddToContextQuery(&query, "a", std::move(selector));

  TestListener listener;
  repository_.AddSubscription(std::move(query), &listener,
                              fuchsia::modular::SubscriptionDebugInfo());
  ASSERT_TRUE(listener.last_update);
  auto maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  {
    auto& result = maybe_result.value();
    EXPECT_EQ(0lu, result.size());
    listener.reset();
  }

  // Add a Story value.
  fuchsia::modular::ContextValue story_value;
  story_value.type = fuchsia::modular::ContextValueType::STORY;
  story_value.meta = ContextMetadataBuilder().SetStoryId("no match").Build();
  fuchsia::modular::ContextValue first_story_value;
  fidl::Clone(story_value, &first_story_value);  // Save for later.
  auto story_value_id = repository_.Add(std::move(story_value));

  // Expect no update.
  EXPECT_FALSE(listener.last_update);

  // Add an fuchsia::modular::Entity node, but it still shouldn't match.
  fuchsia::modular::ContextValue entity_value;
  entity_value.type = fuchsia::modular::ContextValueType::ENTITY;
  entity_value.content = "content";
  repository_.Add(story_value_id, std::move(entity_value));

  // Still expect no update.
  EXPECT_FALSE(listener.last_update);

  // Update the story value so its metadata matches the query, and we should
  // see the entity value returned in our update.
  story_value = fuchsia::modular::ContextValue();
  story_value.type = fuchsia::modular::ContextValueType::STORY;
  story_value.meta = ContextMetadataBuilder().SetStoryId("match").Build();
  fuchsia::modular::ContextValue matching_story_value;
  fidl::Clone(story_value, &matching_story_value);  // Save for later.
  repository_.Update(story_value_id, std::move(story_value));

  ASSERT_TRUE(listener.last_update);
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  {
    auto& result = maybe_result.value();
    EXPECT_EQ(1lu, result.size());
    EXPECT_EQ("content", result.at(0).content);
    // Make sure we adopted the parent metadata from the story node.
    ASSERT_TRUE(result.at(0).meta.story);
    EXPECT_EQ("match", result.at(0).meta.story->id);
  }
  listener.reset();

  // Set the value back to something that doesn't match, and we should get an
  // empty update.
  repository_.Update(story_value_id, std::move(first_story_value));
  ASSERT_TRUE(listener.last_update);
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  EXPECT_EQ(0lu, maybe_result.value().size());
  listener.reset();

  // Set it back to something that matched, and this time remove the value
  // entirely. We should observe it go away.
  repository_.Update(story_value_id, std::move(matching_story_value));
  ASSERT_TRUE(listener.last_update);
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  EXPECT_EQ(1lu, maybe_result.value().size());
  listener.reset();

  repository_.Remove(story_value_id);
  ASSERT_TRUE(listener.last_update);
  maybe_result = TakeContextValue(listener.last_update.get(), "a");
  ASSERT_TRUE(maybe_result.has_value());
  EXPECT_TRUE(maybe_result.value().empty());
  listener.reset();
}

}  // namespace modular
