// 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,
    std::vector<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,
               std::vector<fuchsia::modular::StoryCommand> commands ={}) {
    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,
               std::vector<fuchsia::modular::StoryCommand> commands = {}) {
    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) {
    std::vector<fuchsia::modular::StoryCommand> commands;
    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,
      std::vector<fuchsia::modular::StoryCommand> commands ={}) {
    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_;
  std::vector<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(std::string 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));
  std::vector<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));
  std::vector<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
