// Copyright 2016 The Chromium 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 COMPONENTS_NTP_SNIPPETS_CONTENT_SUGGESTIONS_SERVICE_H_
#define COMPONENTS_NTP_SNIPPETS_CONTENT_SUGGESTIONS_SERVICE_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/time/time.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/ntp_snippets/callbacks.h"
#include "components/ntp_snippets/category.h"
#include "components/ntp_snippets/category_rankers/category_ranker.h"
#include "components/ntp_snippets/category_status.h"
#include "components/ntp_snippets/content_suggestions_provider.h"
#include "components/ntp_snippets/logger.h"
#include "components/ntp_snippets/remote/remote_suggestions_scheduler.h"
#include "components/ntp_snippets/user_classifier.h"
#include "services/identity/public/cpp/identity_manager.h"

class PrefService;
class PrefRegistrySimple;

namespace favicon {
class LargeIconService;
}  // namespace favicon

namespace favicon_base {
struct LargeIconImageResult;
}  // namespace favicon_base

namespace ntp_snippets {

class RemoteSuggestionsProvider;

// Retrieves suggestions from a number of ContentSuggestionsProviders and serves
// them grouped into categories. There can be at most one provider per category.
class ContentSuggestionsService : public KeyedService,
                                  public ContentSuggestionsProvider::Observer,
                                  public identity::IdentityManager::Observer,
                                  public history::HistoryServiceObserver {
 public:
  class Observer {
   public:
    // Fired every time the service receives a new set of data for the given
    // |category|, replacing any previously available data (though in most cases
    // there will be an overlap and only a few changes within the data). The new
    // data is then available through |GetSuggestionsForCategory(category)|.
    virtual void OnNewSuggestions(Category category) = 0;

    // Fired when the status of a suggestions category changed. Note that for
    // some status changes, the UI must update immediately (e.g. to remove
    // invalidated suggestions). See comments on the individual CategoryStatus
    // values for details.
    virtual void OnCategoryStatusChanged(Category category,
                                         CategoryStatus new_status) = 0;

    // Fired when a suggestion has been invalidated. The UI must immediately
    // clear the suggestion even from open NTPs. Invalidation happens, for
    // example, when the content that the suggestion refers to is gone.
    // Note that this event may be fired even if the corresponding category is
    // not currently AVAILABLE, because open UIs may still be showing the
    // suggestion that is to be removed. This event may also be fired for
    // |suggestion_id|s that never existed and should be ignored in that case.
    virtual void OnSuggestionInvalidated(
        const ContentSuggestion::ID& suggestion_id) = 0;

    // Fired when the previously sent data is not valid anymore and a refresh
    // of all the suggestions is required. Called for example when the sign in
    // state changes and personalised suggestions have to be shown or discarded.
    virtual void OnFullRefreshRequired() = 0;

    // Sent when the service is shutting down. After the service has shut down,
    // it will not provide any data anymore, though calling the getters is still
    // safe.
    virtual void ContentSuggestionsServiceShutdown() = 0;

   protected:
    virtual ~Observer() = default;
  };

  enum class State {
    ENABLED,
    DISABLED,
  };

  ContentSuggestionsService(
      State state,
      identity::IdentityManager*
          identity_manager,                      // Can be nullptr in unittests.
      history::HistoryService* history_service,  // Can be nullptr in unittests.
      // Can be nullptr in unittests.
      favicon::LargeIconService* large_icon_service,
      PrefService* pref_service,
      std::unique_ptr<CategoryRanker> category_ranker,
      std::unique_ptr<UserClassifier> user_classifier,
      std::unique_ptr<RemoteSuggestionsScheduler>
          remote_suggestions_scheduler,  // Can be nullptr in unittests.
      std::unique_ptr<Logger> debug_logger);
  ~ContentSuggestionsService() override;

  // Inherited from KeyedService.
  void Shutdown() override;

  static void RegisterProfilePrefs(PrefRegistrySimple* registry);

  State state() { return state_; }

  // Gets all categories for which a provider is registered. The categories may
  // or may not be available, see |GetCategoryStatus()|. The order in which the
  // categories are returned is the order in which they should be displayed.
  std::vector<Category> GetCategories() const;

  // Gets the status of a category.
  CategoryStatus GetCategoryStatus(Category category) const;

  // Gets the meta information of a category.
  base::Optional<CategoryInfo> GetCategoryInfo(Category category) const;

  // Gets the available suggestions for a category. The result is empty if the
  // category is available and empty, but also if the category is unavailable
  // for any reason, see |GetCategoryStatus()|.
  const std::vector<ContentSuggestion>& GetSuggestionsForCategory(
      Category category) const;

  // Fetches the image for the suggestion with the given |suggestion_id| and
  // runs the |callback|. If that suggestion doesn't exist or the fetch fails,
  // the callback gets an empty image. The callback will not be called
  // synchronously.
  void FetchSuggestionImage(const ContentSuggestion::ID& suggestion_id,
                            ImageFetchedCallback callback);

  // Fetches the image data for the suggestion with the given |suggestion_id|
  // and runs the |callback|. If that suggestion doesn't exist or the fetch
  // fails, the callback gets empty data. The callback will not be called
  // synchronously.
  void FetchSuggestionImageData(const ContentSuggestion::ID& suggestion_id,
                                ImageDataFetchedCallback callback);

  // Fetches the favicon from local cache (if larger than or equal to
  // |minimum_size_in_pixel|) or from Google server (if there is no icon in the
  // cache) and returns the results in the callback. If that suggestion doesn't
  // exist or the fetch fails, the callback gets an empty image. The callback
  // will not be called synchronously.
  void FetchSuggestionFavicon(const ContentSuggestion::ID& suggestion_id,
                              int minimum_size_in_pixel,
                              int desired_size_in_pixel,
                              ImageFetchedCallback callback);

  // Dismisses the suggestion with the given |suggestion_id|, if it exists.
  // This will not trigger an update through the observers (i.e. providers must
  // not call |Observer::OnNewSuggestions|).
  void DismissSuggestion(const ContentSuggestion::ID& suggestion_id);

  // Dismisses the given |category|, if it exists.
  // This will not trigger an update through the observers.
  void DismissCategory(Category category);

  // Restores all dismissed categories.
  // This will not trigger an update through the observers.
  void RestoreDismissedCategories();

  // Returns whether |category| is dismissed.
  bool IsCategoryDismissed(Category category) const;

  // Fetches additional contents for the given |category|. If the fetch was
  // completed, the given |callback| is called with the updated content.
  // This includes new and old data.
  // TODO(jkrcal): Consider either renaming this to FetchMore or unify the ways
  // to get suggestions to just this async Fetch() API.
  void Fetch(const Category& category,
             const std::set<std::string>& known_suggestion_ids,
             FetchDoneCallback callback);

  // Reloads suggestions from all categories, from all providers. If a provider
  // naturally has some ability to generate fresh suggestions, it may provide a
  // completely new set of suggestions. If the provider has no ability to
  // generate fresh suggestions on demand, it may only fill in any vacant space
  // by suggestions that were previously not included due to space limits (there
  // may be vacant space because of the user dismissing suggestions in the
  // meantime).
  void ReloadSuggestions();

  // Observer accessors.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Registers a new ContentSuggestionsProvider. It must be ensured that at most
  // one provider is registered for every category and that this method is
  // called only once per provider.
  void RegisterProvider(std::unique_ptr<ContentSuggestionsProvider> provider);

  // Removes history from the specified time range where the URL matches the
  // |filter| from all providers. The data removed depends on the provider. Note
  // that the data outside the time range may be deleted, for example
  // suggestions, which are based on history from that time range. Providers
  // should immediately clear any data related to history from the specified
  // time range where the URL matches the |filter|.
  void ClearHistory(base::Time begin,
                    base::Time end,
                    const base::Callback<bool(const GURL& url)>& filter);

  // Removes all suggestions from all caches or internal stores in all
  // providers. It does, however, not remove any suggestions from the provider's
  // sources, so if its configuration hasn't changed, it might return the same
  // results when it fetches the next time. In particular, calling this method
  // will not mark any suggestions as dismissed.
  void ClearAllCachedSuggestions();

  // Only for debugging use through the internals page.
  // Retrieves suggestions of the given |category| that have previously been
  // dismissed and are still stored in the respective provider. If the
  // provider doesn't store dismissed suggestions, the callback receives an
  // empty vector. The callback may be called synchronously.
  void GetDismissedSuggestionsForDebugging(
      Category category,
      DismissedSuggestionsCallback callback);

  // Only for debugging use through the internals page. Some providers
  // internally store a list of dismissed suggestions to prevent them from
  // reappearing. This function clears all suggestions of the given |category|
  // from such lists, making dismissed suggestions reappear (if the provider
  // supports it).
  void ClearDismissedSuggestionsForDebugging(Category category);

  std::string GetDebugLog() const {
    return debug_logger_->GetHumanReadableLog();
  }

  // Returns true if the remote suggestions provider is enabled.
  bool AreRemoteSuggestionsEnabled() const;

  // The reference to the RemoteSuggestionsProvider provider should
  // only be set by the factory and only used for debugging.
  // TODO(jkrcal) The way we deal with the circular dependency feels wrong.
  // Consider swapping the dependencies: first constructing all providers, then
  // constructing the service (passing the remote provider as arg), finally
  // registering the service as an observer of all providers?
  // TODO(jkrcal) Move the getter into the scheduler interface (the setter is
  // then not needed any more). crbug.com/695447
  void set_remote_suggestions_provider(
      RemoteSuggestionsProvider* remote_suggestions_provider) {
    remote_suggestions_provider_ = remote_suggestions_provider;
  }
  RemoteSuggestionsProvider* remote_suggestions_provider_for_debugging() {
    return remote_suggestions_provider_;
  }

  // The interface is suited for informing about external events that have
  // influence on scheduling remote fetches. Can be nullptr in tests.
  RemoteSuggestionsScheduler* remote_suggestions_scheduler() {
    return remote_suggestions_scheduler_.get();
  }

  // Can be nullptr in tests.
  // TODO(jkrcal): The getter is only used from the bridge and from
  // snippets-internals. Can we get rid of it with the metrics refactoring?
  UserClassifier* user_classifier() { return user_classifier_.get(); }

  CategoryRanker* category_ranker() { return category_ranker_.get(); }

  Logger* debug_logger() { return debug_logger_.get(); }

 private:
  friend class ContentSuggestionsServiceTest;

  // Implementation of ContentSuggestionsProvider::Observer.
  void OnNewSuggestions(ContentSuggestionsProvider* provider,
                        Category category,
                        std::vector<ContentSuggestion> suggestions) override;
  void OnCategoryStatusChanged(ContentSuggestionsProvider* provider,
                               Category category,
                               CategoryStatus new_status) override;
  void OnSuggestionInvalidated(
      ContentSuggestionsProvider* provider,
      const ContentSuggestion::ID& suggestion_id) override;

  // identity::IdentityManager::Observer implementation.
  void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override;
  void OnPrimaryAccountCleared(const CoreAccountInfo& account_info) override;

  // history::HistoryServiceObserver implementation.
  void OnURLsDeleted(history::HistoryService* history_service,
                     const history::DeletionInfo& deletion_info) override;
  void HistoryServiceBeingDeleted(
      history::HistoryService* history_service) override;

  // Registers the given |provider| for the given |category|, unless it is
  // already registered. Returns true if the category was newly registered or
  // false if it is dismissed or was present before.
  bool TryRegisterProviderForCategory(ContentSuggestionsProvider* provider,
                                      Category category);
  void RegisterCategory(Category category,
                        ContentSuggestionsProvider* provider);
  void UnregisterCategory(Category category,
                          ContentSuggestionsProvider* provider);

  // Removes a suggestion from the local store |suggestions_by_category_|, if it
  // exists. Returns true if a suggestion was removed.
  bool RemoveSuggestionByID(const ContentSuggestion::ID& suggestion_id);

  // Fires the OnCategoryStatusChanged event for the given |category|.
  void NotifyCategoryStatusChanged(Category category);

  void OnSignInStateChanged(bool has_signed_in);

  // Re-enables a dismissed category, making querying its provider possible.
  void RestoreDismissedCategory(Category category);

  void RestoreDismissedCategoriesFromPrefs();
  void StoreDismissedCategoriesToPrefs();

  // Not implemented for articles. For all other categories, destroys its
  // provider, deletes all mentions (except from dismissed list) and notifies
  // observers that the category is disabled.
  void DestroyCategoryAndItsProvider(Category category);

  // Get the domain of the suggestion suitable for fetching the favicon.
  GURL GetFaviconDomain(const ContentSuggestion::ID& suggestion_id);

  // Initiate the fetch of a favicon from the local cache.
  void GetFaviconFromCache(const GURL& publisher_url,
                           int minimum_size_in_pixel,
                           int desired_size_in_pixel,
                           ImageFetchedCallback callback,
                           bool continue_to_google_server);

  // Callbacks for fetching favicons.
  void OnGetFaviconFromCacheFinished(
      const GURL& publisher_url,
      int minimum_size_in_pixel,
      int desired_size_in_pixel,
      ImageFetchedCallback callback,
      bool continue_to_google_server,
      const favicon_base::LargeIconImageResult& result);
  void OnGetFaviconFromGoogleServerFinished(
      const GURL& publisher_url,
      int minimum_size_in_pixel,
      int desired_size_in_pixel,
      ImageFetchedCallback callback,
      favicon_base::GoogleFaviconServerRequestStatus status);

  // Whether the content suggestions feature is enabled.
  State state_;

  // All registered providers, owned by the service.
  std::vector<std::unique_ptr<ContentSuggestionsProvider>> providers_;

  // All registered categories and their providers. A provider may be contained
  // multiple times, if it provides multiple categories. The keys of this map
  // are exactly the entries of |categories_| and the values are a subset of
  // |providers_|.
  std::map<Category, ContentSuggestionsProvider*, Category::CompareByID>
      providers_by_category_;

  // All dismissed categories and their providers. These may be restored by
  // RestoreDismissedCategories(). The provider can be null if the dismissed
  // category has received no updates since initialisation.
  // (see RestoreDismissedCategoriesFromPrefs())
  std::map<Category, ContentSuggestionsProvider*, Category::CompareByID>
      dismissed_providers_by_category_;

  // All current suggestion categories in arbitrary order. This vector contains
  // exactly the same categories as |providers_by_category_|.
  std::vector<Category> categories_;

  // All current suggestions grouped by category. This contains an entry for
  // every category in |categories_| whose status is an available status. It may
  // contain an empty vector if the category is available but empty (or still
  // loading).
  std::map<Category, std::vector<ContentSuggestion>, Category::CompareByID>
      suggestions_by_category_;

  // Observer for the IdentityManager. All observers are notified when the
  // signin state changes so that they can refresh their list of suggestions.
  ScopedObserver<identity::IdentityManager, identity::IdentityManager::Observer>
      identity_manager_observer_;

  // Observer for the HistoryService. All providers are notified when history is
  // deleted.
  ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
      history_service_observer_;

  base::ObserverList<Observer>::Unchecked observers_;

  const std::vector<ContentSuggestion> no_suggestions_;

  base::CancelableTaskTracker favicons_task_tracker_;

  // Keep a direct reference to this special provider to redirect debugging
  // calls to it. If the RemoteSuggestionsProvider is loaded, it is also present
  // in |providers_|, otherwise this is a nullptr.
  RemoteSuggestionsProvider* remote_suggestions_provider_;

  favicon::LargeIconService* large_icon_service_;

  PrefService* pref_service_;

  // Interface for informing about external events that have influence on
  // scheduling remote fetches.
  std::unique_ptr<RemoteSuggestionsScheduler> remote_suggestions_scheduler_;

  // Classifies the user on the basis of long-term user interactions.
  std::unique_ptr<UserClassifier> user_classifier_;

  // Provides order for categories.
  std::unique_ptr<CategoryRanker> category_ranker_;

  std::unique_ptr<Logger> debug_logger_;

  DISALLOW_COPY_AND_ASSIGN(ContentSuggestionsService);
};

}  // namespace ntp_snippets

#endif  // COMPONENTS_NTP_SNIPPETS_CONTENT_SUGGESTIONS_SERVICE_H_
