// Copyright 2015 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_NTP_SNIPPETS_SERVICE_H_
#define COMPONENTS_NTP_SNIPPETS_NTP_SNIPPETS_SERVICE_H_

#include <stddef.h>

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

#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/timer/timer.h"
#include "components/image_fetcher/image_fetcher_delegate.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/ntp_snippets/content_suggestion.h"
#include "components/ntp_snippets/content_suggestions_category.h"
#include "components/ntp_snippets/content_suggestions_category_status.h"
#include "components/ntp_snippets/content_suggestions_provider.h"
#include "components/ntp_snippets/ntp_snippet.h"
#include "components/ntp_snippets/ntp_snippets_fetcher.h"
#include "components/ntp_snippets/ntp_snippets_scheduler.h"
#include "components/ntp_snippets/ntp_snippets_status_service.h"
#include "components/suggestions/suggestions_service.h"
#include "components/sync_driver/sync_service_observer.h"

class PrefRegistrySimple;
class PrefService;
class SigninManagerBase;

namespace base {
class RefCountedMemory;
class Value;
}

namespace gfx {
class Image;
}

namespace image_fetcher {
class ImageDecoder;
class ImageFetcher;
}

namespace suggestions {
class SuggestionsProfile;
}

namespace sync_driver {
class SyncService;
}

namespace ntp_snippets {

class NTPSnippetsDatabase;
class NTPSnippetsServiceObserver;

// Stores and vends fresh content data for the NTP.
// TODO(pke): Rename this service to ArticleSuggestionsService and move to
// a subdirectory.
class NTPSnippetsService : public KeyedService,
                           public image_fetcher::ImageFetcherDelegate,
                           public ContentSuggestionsProvider {
 public:
  using ImageFetchedCallback =
      base::Callback<void(const std::string& suggestion_id, const gfx::Image&)>;

  // |application_language_code| should be a ISO 639-1 compliant string, e.g.
  // 'en' or 'en-US'. Note that this code should only specify the language, not
  // the locale, so 'en_US' (English language with US locale) and 'en-GB_US'
  // (British English person in the US) are not language codes.
  NTPSnippetsService(bool enabled,
                     PrefService* pref_service,
                     suggestions::SuggestionsService* suggestions_service,
                     const std::string& application_language_code,
                     NTPSnippetsScheduler* scheduler,
                     std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher,
                     std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
                     std::unique_ptr<image_fetcher::ImageDecoder> image_decoder,
                     std::unique_ptr<NTPSnippetsDatabase> database,
                     std::unique_ptr<NTPSnippetsStatusService> status_service);

  ~NTPSnippetsService() override;

  static void RegisterProfilePrefs(PrefRegistrySimple* registry);

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

  // Returns whether the service is ready. While this is false, the list of
  // snippets will be empty, and all modifications to it (fetch, discard, etc)
  // will be ignored.
  bool ready() const { return state_ == State::READY; }

  // Returns whether the service is initialized. While this is false, some
  // calls may trigger DCHECKs.
  bool initialized() const { return ready() || state_ == State::DISABLED; }

  // Fetches snippets from the server and adds them to the current ones.
  void FetchSnippets();
  // Fetches snippets from the server for specified hosts (overriding
  // suggestions from the suggestion service) and adds them to the current ones.
  // Only called from chrome://snippets-internals, DO NOT USE otherwise!
  // Ignored while |loaded()| is false.
  void FetchSnippetsFromHosts(const std::set<std::string>& hosts);

  // Available snippets.
  const NTPSnippet::PtrVector& snippets() const { return snippets_; }

  // Returns the list of snippets previously discarded by the user (that are
  // not expired yet).
  const NTPSnippet::PtrVector& discarded_snippets() const {
    return discarded_snippets_;
  }

  const NTPSnippetsFetcher* snippets_fetcher() const {
    return snippets_fetcher_.get();
  }

  // Returns a reason why the service is disabled, or DisabledReason::NONE
  // if it's not.
  DisabledReason disabled_reason() const {
    return snippets_status_service_->disabled_reason();
  }

  // (Re)schedules the periodic fetching of snippets. This is necessary because
  // the schedule depends on the time of day.
  void RescheduleFetching();

  // ContentSuggestionsProvider implementation
  // TODO(pke): At some point reorder the implementations in the .cc file
  // accordingly.
  void SetObserver(Observer* observer) override;
  ContentSuggestionsCategoryStatus GetCategoryStatus(
      ContentSuggestionsCategory category) override;
  void DiscardSuggestion(const std::string& suggestion_id) override;
  void FetchSuggestionImage(const std::string& suggestion_id,
                            const ImageFetchedCallback& callback) override;
  void ClearCachedSuggestionsForDebugging() override;
  void ClearDiscardedSuggestionsForDebugging() override;

  // Returns the lists of suggestion hosts the snippets are restricted to.
  std::set<std::string> GetSuggestionsHosts() const;

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

  // Returns the maximum number of snippets that will be shown at once.
  static int GetMaxSnippetCountForTesting();

 private:
  FRIEND_TEST_ALL_PREFIXES(NTPSnippetsServiceTest, HistorySyncStateChanges);

  // TODO(pke): As soon as the DisabledReason is replaced with the new status,
  // also remove the old State enum and replace it with
  // ContentSuggestionsCategoryStatus and a similar status diagram.
  // Possible state transitions:
  //  +------- NOT_INITED ------+
  //  |        /       \        |
  //  |   READY <--> DISABLED <-+
  //  |       \        /
  //  +-----> SHUT_DOWN
  enum class State {
    // The service has just been created. Can change to states:
    // - DISABLED: if the constructor was called with |enabled == false| . In
    //             that case the service will stay disabled until it is shut
    //             down. It can also enter this state after the database is
    //             done loading and GetStateForDependenciesStatus identifies
    //             the next state to be DISABLED.
    // - READY: if GetStateForDependenciesStatus returns it, after the database
    //          is done loading.
    NOT_INITED,

    // The service registered observers, timers, etc. and is ready to answer to
    // queries, fetch snippets... Can change to states:
    // - DISABLED: when the global Chrome state changes, for example after
    //             |OnStateChanged| is called and sync is disabled.
    // - SHUT_DOWN: when |Shutdown| is called, during the browser shutdown.
    READY,

    // The service is disabled and unregistered the related resources.
    // Can change to states:
    // - READY: when the global Chrome state changes, for example after
    //          |OnStateChanged| is called and sync is enabled.
    // - SHUT_DOWN: when |Shutdown| is called, during the browser shutdown.
    DISABLED,

    // The service shutdown and can't be used anymore. This state is checked
    // for early exit in callbacks from observers.
    SHUT_DOWN
  };

  // image_fetcher::ImageFetcherDelegate implementation.
  void OnImageDataFetched(const std::string& snippet_id,
                          const std::string& image_data) override;

  // Callbacks for the NTPSnippetsDatabase.
  void OnDatabaseLoaded(NTPSnippet::PtrVector snippets);
  void OnDatabaseError();

  // Callback for the SuggestionsService.
  void OnSuggestionsChanged(const suggestions::SuggestionsProfile& suggestions);

  // Callback for the NTPSnippetsFetcher.
  void OnFetchFinished(NTPSnippetsFetcher::OptionalSnippets snippets);

  // Merges newly available snippets with the previously available list.
  void MergeSnippets(NTPSnippet::PtrVector new_snippets);

  std::set<std::string> GetSnippetHostsFromPrefs() const;
  void StoreSnippetHostsToPrefs(const std::set<std::string>& hosts);

  // Removes the expired snippets (including discarded) from the service and the
  // database, and schedules another pass for the next expiration.
  void ClearExpiredSnippets();

  // Completes the initialization phase of the service, registering the last
  // observers. This is done after construction, once the database is loaded.
  void FinishInitialization();

  void LoadingSnippetsFinished();

  void OnSnippetImageFetchedFromDatabase(const std::string& snippet_id,
                                         const ImageFetchedCallback& callback,
                                         std::string data);

  void OnSnippetImageDecoded(const std::string& snippet_id,
                             const ImageFetchedCallback& callback,
                             const gfx::Image& image);

  void FetchSnippetImageFromNetwork(const std::string& snippet_id,
                                    const ImageFetchedCallback& callback);

  // Triggers a state transition depending on the provided reason to be
  // disabled (or lack thereof). This method is called when a change is detected
  // by |snippets_status_service_|
  void UpdateStateForStatus(DisabledReason disabled_reason);

  // Verifies state transitions (see |State|'s documentation) and applies them.
  // Also updates the provider status. Does nothing except updating the provider
  // status if called with the current state.
  void EnterState(State state, ContentSuggestionsCategoryStatus status);

  // Enables the service and triggers a fetch if required. Do not call directly,
  // use |EnterState| instead.
  void EnterStateEnabled(bool fetch_snippets);

  // Disables the service. Do not call directly, use |EnterState| instead.
  void EnterStateDisabled();

  // Applies the effects of the transition to the SHUT_DOWN state. Do not call
  // directly, use |EnterState| instead.
  void EnterStateShutdown();

  // Converts the cached snippets to article content suggestions and notifies
  // the observers.
  void NotifyNewSuggestions();

  // Notifies the content suggestions observer about a change in the
  // |category_status_|.
  void NotifyCategoryStatusChanged();

  State state_;

  ContentSuggestionsCategoryStatus category_status_;

  PrefService* pref_service_;

  suggestions::SuggestionsService* suggestions_service_;

  // All current suggestions (i.e. not discarded ones).
  NTPSnippet::PtrVector snippets_;

  // Suggestions that the user discarded. We keep these around until they expire
  // so we won't re-add them on the next fetch.
  NTPSnippet::PtrVector discarded_snippets_;

  // The ISO 639-1 code of the language used by the application.
  const std::string application_language_code_;

  // The observers.
  // TODO(pke): This is an old kind of observers that will be removed.
  base::ObserverList<NTPSnippetsServiceObserver> observers_;

  // The observer to deliver data to.
  Observer* observer_;

  // Scheduler for fetching snippets. Not owned.
  NTPSnippetsScheduler* scheduler_;

  // The subscription to the SuggestionsService. When the suggestions change,
  // SuggestionsService will call |OnSuggestionsChanged|, which triggers an
  // update to the set of snippets.
  using SuggestionsSubscription =
      suggestions::SuggestionsService::ResponseCallbackList::Subscription;
  std::unique_ptr<SuggestionsSubscription> suggestions_service_subscription_;

  // The snippets fetcher.
  std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher_;

  // Timer that calls us back when the next snippet expires.
  base::OneShotTimer expiry_timer_;

  std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
  std::unique_ptr<image_fetcher::ImageDecoder> image_decoder_;

  // The database for persisting snippets.
  std::unique_ptr<NTPSnippetsDatabase> database_;

  // The service that provides events and data about the signin and sync state.
  std::unique_ptr<NTPSnippetsStatusService> snippets_status_service_;

  // Set to true if FetchSnippets is called before the database has been loaded.
  // The fetch will be executed after the database load finishes.
  bool fetch_after_load_;

  DISALLOW_COPY_AND_ASSIGN(NTPSnippetsService);
};

// TODO(pke): Remove this when snippets internals don't access this service
// directly anymore.
class NTPSnippetsServiceObserver {
 public:
  // Sent every time the service loads a new set of data.
  virtual void NTPSnippetsServiceLoaded() = 0;

  // Sent when the service is shutting down.
  virtual void NTPSnippetsServiceShutdown() = 0;

  // Sent when the state of the service is changing. Something changed in its
  // dependencies so it's notifying observers about incoming data changes.
  // If the service might be enabled, DisabledReason::NONE will be provided.
  virtual void NTPSnippetsServiceDisabledReasonChanged(DisabledReason) = 0;

 protected:
  virtual ~NTPSnippetsServiceObserver() {}
};

}  // namespace ntp_snippets

#endif  // COMPONENTS_NTP_SNIPPETS_NTP_SNIPPETS_SERVICE_H_
