// 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.

#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_PROCESSOR_H_
#define PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_PROCESSOR_H_

#include <set>

#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/modular/cpp/fidl.h>
#include <src/lib/fxl/memory/weak_ptr.h>

#include "peridot/bin/suggestion_engine/media_player.h"
#include "peridot/bin/suggestion_engine/query_runner.h"
#include "peridot/bin/suggestion_engine/rankers/ranker.h"
#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
#include "peridot/lib/util/idle_waiter.h"

namespace modular {

class SuggestionEngineImpl;

// The query processor handles the pull-based query suggestion process,
// including requesting suggestions from QueryHandlers, collating and
// ranking those suggestions, and then providing them to the user.
class QueryProcessor {
 public:
  QueryProcessor(std::shared_ptr<SuggestionDebugImpl> debug);
  ~QueryProcessor();

  void Initialize(
      fidl::InterfaceHandle<fuchsia::modular::ContextWriter> context_writer);

  // Runs a query and notifies listener with results from it with the given
  // input and providing 'count' results. It also caches all query results for
  // future fetching using GetSuggestion(). Each time ExecuteQuery is called,
  // suggestions from the previous query are cleared by calling
  // CleanUpPreviousQuery() internally.
  void ExecuteQuery(
      fuchsia::modular::UserInput input, int count,
      fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener);

  // Registers a handler that will be notified when a new query comes for its
  // fullfillment.
  void RegisterQueryHandler(
      fidl::StringPtr url, fidl::InterfaceHandle<fuchsia::modular::QueryHandler>
                               query_handler_handle);

  void SetFilters(
      std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters,
      std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters);

  void SetRanker(std::unique_ptr<Ranker> ranker);

  // Returns a query suggestion with the given id.
  // While a query is being executed or if no query has been executed, nullptr
  // will be returned for any |suggestion_id|. If |suggestion_id| is not in the
  // set of results given to the |listener| provided to the most recent
  // invocation of ExecuteQuery(), return nullptr.
  RankedSuggestion* GetSuggestion(const std::string& suggestion_uuid) const;

  // Cleans up all resources associated with a query, including clearing
  // the previous ask suggestions, closing any still open SuggestionListeners,
  // etc.
  void CleanUpPreviousQuery();

 private:
  // (proposer ID, proposal ID) => suggestion prototype
  using SuggestionPrototypeMap = std::map<std::pair<std::string, std::string>,
                                          std::unique_ptr<SuggestionPrototype>>;

  void AddProposal(const std::string& source_url,
                   fuchsia::modular::Proposal proposal);

  void OnQueryResponse(fuchsia::modular::UserInput input,
                       const std::string& handler_url,
                       fuchsia::modular::QueryResponse response);

  void OnQueryEndRequest(fuchsia::modular::UserInput input);

  void NotifyOfResults();

  std::shared_ptr<SuggestionDebugImpl> debug_;
  RankedSuggestionsList suggestions_;
  SuggestionPrototypeMap query_prototypes_;

  // Unique ptr for the query runner executing the query being processed.
  std::unique_ptr<QueryRunner> active_query_;

  // The fuchsia::modular::ContextWriter that publishes the current user query
  // to the fuchsia::modular::ContextEngine.
  fuchsia::modular::ContextWriterPtr context_writer_;

  // The set of all QueryHandlers that have been registered mapped to their
  // URLs (stored as strings).
  std::vector<QueryHandlerRecord> query_handlers_;

  util::IdleWaiter::ActivityToken activity_;
};

}  // namespace modular

#endif  // PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_PROCESSOR_H_
