// Copyright 2016 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/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/context/cpp/context_helper.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/optional.h>
#include <lib/fxl/logging.h>
#include <lib/svc/cpp/services.h>

#include "peridot/lib/rapidjson/rapidjson.h"
#include "peridot/lib/testing/story_provider_mock.h"
#include "peridot/lib/testing/wait_until_idle.h"
#include "peridot/tests/maxwell_integration/context_engine_test_base.h"
#include "peridot/tests/maxwell_integration/test_suggestion_listener.h"
#include "rapidjson/document.h"
#include "rapidjson/pointer.h"

namespace maxwell {
namespace {

// context agent that publishes an int n
class NWriter {
 public:
  NWriter(fuchsia::modular::ContextEngine* context_engine) {
    fuchsia::modular::ComponentScope scope;
    scope.set_global_scope(fuchsia::modular::GlobalScope());
    context_engine->GetWriter(std::move(scope), pub_.NewRequest());
  }

  void Publish(int n) { pub_->WriteEntityTopic("n", std::to_string(n)); }

 private:
  fuchsia::modular::ContextWriterPtr pub_;
};

fuchsia::modular::Proposal CreateProposal(
    const std::string& id, const std::string& headline,
    fidl::VectorPtr<fuchsia::modular::StoryCommand> commands,
    fuchsia::modular::AnnoyanceType annoyance) {
  fuchsia::modular::Proposal p;
  p.id = id;
  p.on_selected = std::move(commands);
  p.affinity.resize(0);
  fuchsia::modular::SuggestionDisplay d;

  d.headline = headline;
  d.color = 0x00aa00aa;  // argb purple
  d.annoyance = annoyance;

  p.display = std::move(d);
  return p;
}

class Proposinator {
 public:
  Proposinator(fuchsia::modular::SuggestionEngine* suggestion_engine,
               fidl::StringPtr url = "Proposinator") {
    suggestion_engine->RegisterProposalPublisher("Proposinator",
                                                 out_.NewRequest());
  }

  virtual ~Proposinator() = default;

  void Propose(const std::string& id,
               fidl::VectorPtr<fuchsia::modular::StoryCommand> commands =
                   fidl::VectorPtr<fuchsia::modular::StoryCommand>::New(0)) {
    Propose(id, id, fuchsia::modular::AnnoyanceType::NONE, std::move(commands));
  }

  void Propose(const std::string& id, const std::string& headline,
               fuchsia::modular::AnnoyanceType annoyance =
                   fuchsia::modular::AnnoyanceType::NONE,
               fidl::VectorPtr<fuchsia::modular::StoryCommand> commands =
                   fidl::VectorPtr<fuchsia::modular::StoryCommand>::New(0)) {
    Propose(CreateProposal(id, headline, std::move(commands), annoyance));
  }

  void Propose(fuchsia::modular::Proposal proposal) {
    out_->Propose(std::move(proposal));
  }

  void Remove(const std::string& id) { out_->Remove(id); }

  void KillPublisher() { out_.Unbind(); }

 protected:
  fuchsia::modular::ProposalPublisherPtr out_;
};

class AskProposinator : public Proposinator,
                        public fuchsia::modular::QueryHandler {
 public:
  AskProposinator(fuchsia::modular::SuggestionEngine* suggestion_engine,
                  async::Loop* loop, fidl::StringPtr url = "AskProposinator")
      : Proposinator(suggestion_engine, url), loop_(loop), ask_binding_(this) {
    fidl::InterfaceHandle<fuchsia::modular::QueryHandler> query_handle;
    ask_binding_.Bind(query_handle.NewRequest());
    suggestion_engine->RegisterQueryHandler(url, std::move(query_handle));
  }

  void OnQuery(fuchsia::modular::UserInput query,
               OnQueryCallback callback) override {
    query_ = fidl::MakeOptional(query);
    query_callback_ = callback;
    query_proposals_.resize(0);

    if (waiting_for_query_) {
      waiting_for_query_ = false;
      async::PostTask(loop_->dispatcher(), [this] { loop_->Quit(); });
    }
  }

  void WaitForQuery() {
    waiting_for_query_ = true;
    loop_->Run();
    loop_->ResetQuit();
  }

  void Commit() {
    fuchsia::modular::QueryResponse response;
    response.proposals = std::move(query_proposals_);
    query_callback_(std::move(response));
  }

  fidl::StringPtr query() const { return query_ ? query_->text : nullptr; }

  void ProposeForAsk(const std::string& id) {
    auto commands = fidl::VectorPtr<fuchsia::modular::StoryCommand>::New(0);
    ProposeForAsk(id, id, fuchsia::modular::AnnoyanceType::NONE,
                  std::move(commands));
  }

  void ProposeForAsk(
      const std::string& id, const std::string& headline,
      fuchsia::modular::AnnoyanceType annoyance =
          fuchsia::modular::AnnoyanceType::NONE,
      fidl::VectorPtr<fuchsia::modular::StoryCommand> commands =
          fidl::VectorPtr<fuchsia::modular::StoryCommand>::New(0)) {
    query_proposals_.push_back(
        CreateProposal(id, headline, std::move(commands), annoyance));
  }

 private:
  async::Loop* const loop_;
  fidl::Binding<fuchsia::modular::QueryHandler> ask_binding_;
  fuchsia::modular::UserInputPtr query_;
  fidl::VectorPtr<fuchsia::modular::Proposal> query_proposals_;
  OnQueryCallback query_callback_;
  bool waiting_for_query_ = false;
};

// maintains the number of proposals specified by the context field "n"
class NProposals : public Proposinator,
                   public fuchsia::modular::ContextListener {
 public:
  NProposals(fuchsia::modular::ContextEngine* context_engine,
             fuchsia::modular::SuggestionEngine* suggestion_engine)
      : Proposinator(suggestion_engine, "NProposals"), listener_binding_(this) {
    fuchsia::modular::ComponentScope scope;
    scope.set_global_scope(fuchsia::modular::GlobalScope());
    context_engine->GetReader(std::move(scope), reader_.NewRequest());

    fuchsia::modular::ContextSelector selector;
    selector.type = fuchsia::modular::ContextValueType::ENTITY;
    selector.meta = fuchsia::modular::ContextMetadata::New();
    selector.meta->entity = fuchsia::modular::EntityMetadata::New();
    selector.meta->entity->topic = "n";
    fuchsia::modular::ContextQuery query;
    modular::AddToContextQuery(&query, "n", std::move(selector));
    reader_->Subscribe(std::move(query), listener_binding_.NewBinding());
  }

  void OnContextUpdate(fuchsia::modular::ContextUpdate update) override {
    auto maybe_result = modular::TakeContextValue(&update, "n");
    if (!maybe_result) {
      FXL_LOG(INFO) << "Expect an update key for every query key.";
    }
    auto& r = maybe_result.value();
    if (r->empty()) {
      return;
    }
    int n = std::stoi(r->at(0).content);

    for (int i = n_; i < n; i++) {
      Propose(std::to_string(i));
    }
    for (int i = n; i < n_; i++) {
      Remove(std::to_string(i));
    }

    n_ = n;
  }

 private:
  fuchsia::modular::ContextReaderPtr reader_;
  fidl::Binding<fuchsia::modular::ContextListener> listener_binding_;

  int n_ = 0;
};

class SuggestionEngineTest : public ContextEngineTestBase,
                             fuchsia::modular::ProposalListener {
 public:
  SuggestionEngineTest() : story_provider_binding_(&story_provider_) {}

  void SetUp() override {
    ContextEngineTestBase::SetUp();

    component::Services suggestion_services =
        StartServices("fuchsia-pkg://fuchsia.com/suggestion_engine#meta/suggestion_engine.cmx");
    suggestion_engine_ =
        suggestion_services
            .ConnectToService<fuchsia::modular::SuggestionEngine>();
    suggestion_provider_ =
        suggestion_services
            .ConnectToService<fuchsia::modular::SuggestionProvider>();
    suggestion_debug_ =
        suggestion_services
            .ConnectToService<fuchsia::modular::SuggestionDebug>();
  }

 protected:
  fuchsia::modular::SuggestionEngine* suggestion_engine() {
    return suggestion_engine_.get();
  }

  fuchsia::modular::SuggestionProvider* suggestion_provider() {
    return suggestion_provider_.get();
  }

  fuchsia::modular::SuggestionDebug* suggestion_debug() {
    return suggestion_debug_.get();
  }

  modular::StoryProviderMock* story_provider() { return &story_provider_; }

  void StartSuggestionAgent(const std::string& url) {
    auto agent_bridge =
        std::make_unique<MaxwellServiceProviderBridge>(root_environment());
    agent_bridge->AddService<fuchsia::modular::ContextReader>(
        [this,
         url](fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
          fuchsia::modular::ComponentScope scope;
          fuchsia::modular::AgentScope agent_scope;
          agent_scope.url = url;
          scope.set_agent_scope(std::move(agent_scope));
          context_engine()->GetReader(std::move(scope), std::move(request));
        });
    agent_bridge->AddService<fuchsia::modular::ProposalPublisher>(
        [this, url](fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher>
                        request) {
          suggestion_engine_->RegisterProposalPublisher(url,
                                                        std::move(request));
        });
    StartAgent(url, std::move(agent_bridge));
  }

  void AcceptSuggestion(const std::string& suggestion_id) {
    Interact(suggestion_id, fuchsia::modular::InteractionType::SELECTED);
  }

  void DismissSuggestion(const std::string& suggestion_id) {
    Interact(suggestion_id, fuchsia::modular::InteractionType::DISMISSED);
  }

  void WaitUntilIdle() {
    ContextEngineTestBase::WaitUntilIdle();
    util::WaitUntilIdle(&suggestion_debug_, &loop_);
  }

  void RunUntilIdle() {
    suggestion_debug()->RunUntilIdle([this] { loop_.Quit(); });
    loop_.Run();
    loop_.ResetQuit();
    loop_.RunUntilIdle();
  }

  void AddProposalListenerBinding(
      fidl::InterfaceRequest<fuchsia::modular::ProposalListener> request) {
    proposal_listener_bindings_.AddBinding(this, std::move(request));
  }

  // The id of the most recently accepted proposal.
  std::string accepted_proposal_id_;

  // The amount of proposals that have been accepted, as indicated by calls to
  // |OnProposalAccepted|.
  int accepted_proposal_count_ = 0;

  // Whether or not a successful create story action has been observed.
  bool created_story_action_;

  // Story ID when a proposal is accepted. This is the ID of a story that was
  // created as result of the execution of a proposal actions, either through
  // AddModule or for a rich suggestion.
  std::string accepted_proposal_story_id_;

 private:
  void Interact(const std::string& suggestion_id,
                fuchsia::modular::InteractionType interaction_type) {
    fuchsia::modular::Interaction interaction;
    interaction.type = interaction_type;
    suggestion_provider_->NotifyInteraction(suggestion_id,
                                            std::move(interaction));
  }

  // |fuchsia::modular::ProposalListener|
  void OnProposalAccepted(fidl::StringPtr proposal_id,
                          fidl::StringPtr story_id) override {
    accepted_proposal_id_ = proposal_id;
    if (!story_id->empty()) {
      created_story_action_ = true;
      accepted_proposal_story_id_ = story_id;
    }
    accepted_proposal_count_++;
  }

  fuchsia::modular::SuggestionEnginePtr suggestion_engine_;
  fuchsia::modular::SuggestionDebugPtr suggestion_debug_;
  fuchsia::modular::SuggestionProviderPtr suggestion_provider_;

  modular::StoryProviderMock story_provider_;
  fidl::Binding<fuchsia::modular::StoryProvider> story_provider_binding_;
  fidl::BindingSet<fuchsia::modular::ProposalListener>
      proposal_listener_bindings_;
};

class AskTest : public virtual SuggestionEngineTest {
 public:
  AskTest()
      : listener_binding_(&listener_),
        debug_listener_binding_(&debug_listener_) {}

  void SetUp() override {
    SuggestionEngineTest::SetUp();

    suggestion_debug()->WatchAskProposals(debug_listener_binding_.NewBinding());
  }

  void CloseAndResetListener() {
    if (listener_binding_.is_bound()) {
      listener_binding_.Unbind();
      listener_.ClearSuggestions();
    }
  }

  void Query(const std::string& query, int count = 10) {
    CloseAndResetListener();
    fuchsia::modular::UserInput input;
    input.type = fuchsia::modular::InputType::TEXT;
    input.text = query;
    suggestion_provider()->Query(listener_binding_.NewBinding(),
                                 std::move(input), count);
  }

  int suggestion_count() const { return listener_.suggestion_count(); }

  modular::TestSuggestionListener* listener() { return &listener_; }

 protected:
  void EnsureDebugMatches() {
    auto& subscriberAsks = listener_.GetSuggestions();
    auto& debugAsks = debug_listener_.GetProposals();
    EXPECT_GE(debugAsks.size(), subscriberAsks.size());
    for (size_t i = 0; i < subscriberAsks.size(); i++) {
      auto& suggestion = subscriberAsks[i];
      auto& proposal = debugAsks[i];
      EXPECT_EQ(suggestion->display.headline, proposal.display.headline);
      EXPECT_EQ(suggestion->display.subheadline, proposal.display.subheadline);
      EXPECT_EQ(suggestion->display.details, proposal.display.details);
    }
  }

 private:
  modular::TestSuggestionListener listener_;
  modular::TestDebugAskListener debug_listener_;
  fidl::Binding<fuchsia::modular::QueryListener> listener_binding_;
  fidl::Binding<fuchsia::modular::AskProposalListener> debug_listener_binding_;
};

class InterruptionTest : public virtual SuggestionEngineTest {
 public:
  InterruptionTest()
      : listener_binding_(&listener_),
        debug_listener_binding_(&debug_listener_) {}

  void SetUp() override {
    SuggestionEngineTest::SetUp();

    suggestion_provider()->SubscribeToInterruptions(
        listener_binding_.NewBinding());
    suggestion_debug()->WatchInterruptionProposals(
        debug_listener_binding_.NewBinding());

    // Make sure we're subscribed before we start the test.
    WaitUntilIdle();
  }

  modular::TestDebugInterruptionListener* debugListener() {
    return &debug_listener_;
  }
  modular::TestSuggestionListener* listener() { return &listener_; }

 protected:
  int suggestion_count() const { return listener_.suggestion_count(); }

  void EnsureDebugMatches() {
    auto& subscriberNexts = listener_.GetSuggestions();
    auto lastInterruption = debug_listener_.get_interrupt_proposal();
    ASSERT_GE(subscriberNexts.size(), 1u);
    auto& suggestion = subscriberNexts[0];
    EXPECT_EQ(suggestion->display.headline, lastInterruption.display.headline);
    EXPECT_EQ(suggestion->display.subheadline,
              lastInterruption.display.subheadline);
    EXPECT_EQ(suggestion->display.details, lastInterruption.display.details);
  }

 private:
  modular::TestSuggestionListener listener_;
  modular::TestDebugInterruptionListener debug_listener_;

  fidl::Binding<fuchsia::modular::InterruptionListener> listener_binding_;
  fidl::Binding<fuchsia::modular::InterruptionProposalListener>
      debug_listener_binding_;
};

class NextTest : public virtual SuggestionEngineTest {
 public:
  NextTest()
      : listener_binding_(&listener_),
        debug_listener_binding_(&debug_listener_) {}

  void SetUp() override {
    SuggestionEngineTest::SetUp();

    suggestion_debug()->WatchNextProposals(
        debug_listener_binding_.NewBinding());
  }

  modular::TestDebugNextListener* debugListener() { return &debug_listener_; }
  modular::TestSuggestionListener* listener() { return &listener_; }

 protected:
  void StartListening(int count) {
    suggestion_provider()->SubscribeToNext(listener_binding_.NewBinding(),
                                           count);
  }

  void CloseAndResetListener() {
    listener_binding_.Unbind();
    listener_.ClearSuggestions();
  }

  void SetResultCount(int count) {
    CloseAndResetListener();
    suggestion_provider()->SubscribeToNext(listener_binding_.NewBinding(),
                                           count);
  }

  int suggestion_count() const { return listener_.suggestion_count(); }

  const fuchsia::modular::Suggestion* GetOnlySuggestion() const {
    return listener_.GetOnlySuggestion();
  }

  void EnsureDebugMatches() {
    auto& subscriberNexts = listener_.GetSuggestions();
    auto& debugNexts = debug_listener_.GetProposals();
    EXPECT_GE(debugNexts.size(), subscriberNexts.size());
    for (size_t i = 0; i < subscriberNexts.size(); i++) {
      auto& suggestion = subscriberNexts[i];
      auto& proposal = debugNexts[i];
      EXPECT_EQ(suggestion->display.headline, proposal.display.headline);
      EXPECT_EQ(suggestion->display.subheadline, proposal.display.subheadline);
      EXPECT_EQ(suggestion->display.details, proposal.display.details);
    }
  }

 private:
  modular::TestSuggestionListener listener_;
  modular::TestDebugNextListener debug_listener_;

  fidl::Binding<fuchsia::modular::NextListener> listener_binding_;
  fidl::Binding<fuchsia::modular::NextProposalListener> debug_listener_binding_;
};

class ResultCountTest : public NextTest {
 public:
  void SetUp() override {
    NextTest::SetUp();

    pub_.reset(new NWriter(context_engine()));
    sub_.reset(new NProposals(context_engine(), suggestion_engine()));
  }

 protected:
  // Publishes signals for n new suggestions to context.
  void PublishNewSignal(int n = 1) { pub_->Publish(n_ += n); }

 private:
  std::unique_ptr<NWriter> pub_;
  std::unique_ptr<NProposals> sub_;
  int n_ = 0;
};

}  // namespace

// Macro rather than method to capture the expectation in the assertion message.
#define CHECK_RESULT_COUNT(expected) ASYNC_EQ(expected, suggestion_count())

TEST_F(ResultCountTest, InitiallyEmpty) {
  StartListening(10);
  WaitUntilIdle();
  EXPECT_EQ(0, suggestion_count());
}

TEST_F(ResultCountTest, OneByOne) {
  StartListening(10);
  PublishNewSignal();
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());

  PublishNewSignal();
  WaitUntilIdle();
  EXPECT_EQ(2, suggestion_count());
}

TEST_F(ResultCountTest, AddOverLimit) {
  StartListening(0);
  PublishNewSignal(3);
  WaitUntilIdle();
  EXPECT_EQ(0, suggestion_count());

  SetResultCount(1);
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());

  SetResultCount(3);
  WaitUntilIdle();
  EXPECT_EQ(3, suggestion_count());

  SetResultCount(5);
  WaitUntilIdle();
  EXPECT_EQ(3, suggestion_count());

  PublishNewSignal(4);
  WaitUntilIdle();
  EXPECT_EQ(5, suggestion_count());
}

TEST_F(ResultCountTest, Clear) {
  StartListening(10);
  PublishNewSignal(3);
  WaitUntilIdle();
  EXPECT_EQ(3, suggestion_count());

  SetResultCount(0);
  WaitUntilIdle();
  EXPECT_EQ(0, suggestion_count());

  SetResultCount(10);
  WaitUntilIdle();
  EXPECT_EQ(3, suggestion_count());
}

TEST_F(ResultCountTest, MultiRemove) {
  StartListening(10);
  PublishNewSignal(3);
  WaitUntilIdle();
  EXPECT_EQ(3, suggestion_count());

  SetResultCount(1);
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());

  SetResultCount(10);
  WaitUntilIdle();
  EXPECT_EQ(3, suggestion_count());
}

// Tests the removal of earlier suggestions, ensuring that suggestion engine can
// handle the case where an agent requests the removal of suggestions in a non-
// LIFO ordering. This exercises some internal shuffling, especially when
// rankings are likewise non-LIFO (where last = lowest-priority).
//
// TODO(rosswang): Currently this test also tests removing higher-ranked
// suggestions. After we have real ranking, add a test for that.
TEST_F(NextTest, Fifo) {
  Proposinator fifo(suggestion_engine());

  StartListening(10);
  fifo.Propose("1");
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  auto uuid_1 = GetOnlySuggestion()->uuid;

  fifo.Propose("2");
  WaitUntilIdle();
  EXPECT_EQ(2, suggestion_count());
  fifo.Remove("1");
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  auto suggestion = GetOnlySuggestion();
  EXPECT_NE(uuid_1, suggestion->uuid);
  EXPECT_EQ("2", suggestion->display.headline);
}

// Tests the removal of earlier suggestions while capped.
// TODO(rosswang): see above TODO
TEST_F(NextTest, CappedFifo) {
  Proposinator fifo(suggestion_engine());

  StartListening(1);
  fifo.Propose("1");
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  auto uuid1 = GetOnlySuggestion()->uuid;

  fifo.Propose("2");
  WaitUntilIdle();
  EXPECT_EQ(uuid1, GetOnlySuggestion()->uuid)
      << "fuchsia::modular::Proposal 2 ranked over proposal 2; test invalid; "
         "update to test "
         "FIFO-ranked proposals.";

  fifo.Remove("1");
  WaitUntilIdle();
  ASSERT_EQ(1, suggestion_count());
  EXPECT_NE(uuid1, GetOnlySuggestion()->uuid);

  EXPECT_EQ("2", GetOnlySuggestion()->display.headline);
}

TEST_F(NextTest, RemoveBeforeSubscribe) {
  Proposinator zombinator(suggestion_engine());

  zombinator.Propose("brains");
  zombinator.Remove("brains");
  WaitUntilIdle();

  StartListening(10);
  WaitUntilIdle();
  EXPECT_EQ(0, suggestion_count());
}

TEST_F(NextTest, SubscribeBeyondController) {
  Proposinator p(suggestion_engine());

  StartListening(10);
  WaitUntilIdle();
  p.Propose("1");
  p.Propose("2");
  WaitUntilIdle();
  EXPECT_EQ(2, suggestion_count());
}

TEST_F(AskTest, DefaultAsk) {
  AskProposinator p(suggestion_engine(), &loop_);

  Query("test query");
  p.WaitForQuery();
  p.ProposeForAsk("1");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());

  Query("test query 2");
  p.WaitForQuery();
  p.ProposeForAsk("2");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  EnsureDebugMatches();
}

/* These tests assume that a string match between the proposal headline
   and the query text factors into suggestion ranking. That ranking
   feature is currently turned off and thus these tests fail, but they
   will pass with it turned on.

#define CHECK_TOP_HEADLINE(h) \
  ASYNC_CHECK(listener()->GetTopSuggestion()->display->headline == h)

TEST_F(AskTest, AskDifferentQueries) {
  AskProposinator p(suggestion_engine(), &loop_);

  Query("The Hottest Band on the Internet");
  p.WaitForQuery();
  p.ProposeForAsk("Mozart's Ghost");
  p.ProposeForAsk("The Hottest Band on the Internet");
  p.Commit();
  WaitUntilIdle();

  CHECK_TOP_HEADLINE("The Hottest Band on the Internet");

  Query("Mozart's Ghost");
  p.WaitForQuery();
  p.ProposeForAsk("Mozart's Ghost");
  p.ProposeForAsk("The Hottest Band on the Internet");
  p.Commit();
  WaitUntilIdle();

  CHECK_TOP_HEADLINE("Mozart's Ghost");
  EnsureDebugMatches();
}

TEST_F(AskTest, ChangeHeadlineRank) {
  AskProposinator p(suggestion_engine(), &loop_);

  Query("test query");
  p.WaitForQuery();
  p.ProposeForAsk("E-mail", "E-mail");
  p.ProposeForAsk("E-vite", "E-vite");
  p.ProposeForAsk("E-card", "E-card");
  p.ProposeForAsk("Music", "Music");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(4, suggestion_count());

  Query("Ca");
  p.WaitForQuery();
  p.ProposeForAsk("E-mail", "E-mail");
  p.ProposeForAsk("E-vite", "E-vite");
  p.ProposeForAsk("E-card", "E-card");
  p.ProposeForAsk("Music", "Music");
  p.Commit();
  WaitUntilIdle();

  // E-card has a 'ca' in the 3rd position, so should be ranked highest.
  CHECK_TOP_HEADLINE("E-card");

  Query("Ca");
  p.WaitForQuery();
  p.ProposeForAsk("E-mail", "E-mail");
  p.ProposeForAsk("E-mail", "Cam");
  p.ProposeForAsk("E-vite", "E-vite");
  p.ProposeForAsk("E-card", "E-card");
  p.ProposeForAsk("Music", "Music");
  p.Commit();
  WaitUntilIdle();

  CHECK_TOP_HEADLINE("Cam");
  EnsureDebugMatches();
  EXPECT_EQ(4, suggestion_count());
}
*/

/* These tests make an assumption that timestamp factors into ranking, which
   it no longer does.  It could be re-enabled if that factor is included again.

#define HEADLINE_EQ(expected, index) \
  EXPECT_EQ(expected, (*listener())[index]->display->headline)

TEST_F(AskTest, AskRanking) {
  AskProposinator p(suggestion_engine(), &loop_);

  Query("");
  p.WaitForQuery();
  p.ProposeForAsk("View E-mail");
  p.ProposeForAsk("Compose E-mail");
  p.ProposeForAsk("Reply to E-mail");
  p.ProposeForAsk("Send E-vites");
  p.ProposeForAsk("E-mail Guests");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(5, suggestion_count());
  // Results should be ranked by timestamp at this point.
  HEADLINE_EQ("View E-mail", 0);
  HEADLINE_EQ("Compose E-mail", 1);
  HEADLINE_EQ("Reply to E-mail", 2);
  HEADLINE_EQ("Send E-vites", 3);
  HEADLINE_EQ("E-mail Guests", 4);
  EnsureDebugMatches();

  Query("e-mail");
  p.WaitForQuery();
  p.ProposeForAsk("View E-mail");
  p.ProposeForAsk("Compose E-mail");
  p.ProposeForAsk("Reply to E-mail");
  p.ProposeForAsk("Send E-vites");
  p.ProposeForAsk("E-mail Guests");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(5, suggestion_count());
  HEADLINE_EQ("View E-mail", 0);
  HEADLINE_EQ("E-mail Guests", 1);
  HEADLINE_EQ("Compose E-mail", 2);
  HEADLINE_EQ("Reply to E-mail", 3);
  EnsureDebugMatches();

  Query("e-mail", 2);
  p.WaitForQuery();
  p.ProposeForAsk("View E-mail");
  p.ProposeForAsk("Compose E-mail");
  p.ProposeForAsk("Reply to E-mail");
  p.ProposeForAsk("Send E-vites");
  p.ProposeForAsk("E-mail Guests");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(2, suggestion_count());
  HEADLINE_EQ("View E-mail", 0);
  HEADLINE_EQ("E-mail Guests", 1);

  Query("Compose", 1);
  p.WaitForQuery();
  p.ProposeForAsk("View E-mail");
  p.ProposeForAsk("Compose E-mail");
  p.ProposeForAsk("Reply to E-mail");
  p.ProposeForAsk("Send E-vites");
  p.ProposeForAsk("E-mail Guests");
  p.Commit();

  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  HEADLINE_EQ("Compose E-mail", 0);
  EnsureDebugMatches();
}
*/

// This test ensures that Suggestion Engine doesn't keep querying dead handlers.
TEST_F(AskTest, DeadAgent) {
  AskProposinator p(suggestion_engine(), &loop_);

  { AskProposinator m(suggestion_engine(), &loop_); }

  Query("test query");
  p.WaitForQuery();
  p.ProposeForAsk("1");
  p.Commit();

  // RunUntilIdle rather than WaitUntilIdle to not wait for the query handler
  // timeout. If we'd need to wait for the timeout, the test should fail.
  RunUntilIdle();

  EXPECT_EQ(1, suggestion_count());
  EXPECT_TRUE(listener()->query_complete());
}

// This test ensures that if a query handler dies while handling a query,
// Suggestion Engine stops waiting for it gracefully.
TEST_F(AskTest, AgentKilledInAction) {
  AskProposinator p(suggestion_engine(), &loop_);

  {
    AskProposinator coulson(suggestion_engine(), &loop_);

    Query("test query");
    p.WaitForQuery();
    p.ProposeForAsk("1");
    p.Commit();

    RunUntilIdle();

    EXPECT_FALSE(listener()->query_complete());
  }

  RunUntilIdle();

  EXPECT_EQ(1, suggestion_count());
  EXPECT_TRUE(listener()->query_complete());
}

class SuggestionFilteringTest : public NextTest {};

TEST_F(SuggestionFilteringTest, Baseline) {
  // Show that without any existing Stories, we see Proposals to launch
  // any story.
  Proposinator p(suggestion_engine());
  StartListening(10);

  fuchsia::modular::Intent intent;
  intent.handler = "foo://bar";
  fuchsia::modular::AddMod add_mod;
  add_mod.mod_name.push_back("foo");
  add_mod.intent = std::move(intent);

  fuchsia::modular::StoryCommand command;
  command.set_add_mod(std::move(add_mod));
  fidl::VectorPtr<fuchsia::modular::StoryCommand> commands;
  commands.push_back(std::move(command));
  p.Propose("1", std::move(commands));
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
}

TEST_F(SuggestionFilteringTest, Baseline_FilterDoesntMatch) {
  // Show that with an existing Story for a URL, we see Proposals to launch
  // other URLs.
  Proposinator p(suggestion_engine());
  StartListening(10);

  // First notify watchers of the fuchsia::modular::StoryProvider that a story
  // already exists.
  fuchsia::modular::StoryInfo story_info;
  story_info.url = "foo://bazzle_dazzle";
  story_info.id = "";
  story_provider()->NotifyStoryChanged(
      std::move(story_info), fuchsia::modular::StoryState::STOPPED,
      fuchsia::modular::StoryVisibilityState::DEFAULT);

  fuchsia::modular::Intent intent;
  intent.handler = "foo://bar";
  fuchsia::modular::AddMod add_mod;
  add_mod.intent = std::move(intent);
  add_mod.mod_name.push_back("foo");

  fuchsia::modular::StoryCommand command;
  command.set_add_mod(std::move(add_mod));
  fidl::VectorPtr<fuchsia::modular::StoryCommand> commands;
  commands.push_back(std::move(command));
  p.Propose("1", std::move(commands));
  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
}

TEST_F(InterruptionTest, SingleInterruption) {
  Proposinator p(suggestion_engine());

  p.Propose("1", "2", fuchsia::modular::AnnoyanceType::INTERRUPT);

  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  EnsureDebugMatches();
}

TEST_F(InterruptionTest, RemovedInterruption) {
  Proposinator p(suggestion_engine());

  p.Propose("1", "2", fuchsia::modular::AnnoyanceType::INTERRUPT);

  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
  EnsureDebugMatches();

  // Removing shouldn't do anything to an interruption
  p.Remove("1");

  WaitUntilIdle();
  EXPECT_EQ(1, suggestion_count());
}

}  // namespace maxwell
