// 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 CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_
#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_

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

#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/engagement/site_engagement_details.mojom.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "third_party/WebKit/public/platform/site_engagement.mojom.h"
#include "ui/base/page_transition_types.h"

namespace base {
class Clock;
}

namespace banners {
FORWARD_DECLARE_TEST(AppBannerManagerBrowserTest,
                     CheckOnLoadWithoutSufficientEngagement);
}

namespace content {
class WebContents;
}

namespace history {
class HistoryService;
}

class GURL;
class HostContentSettingsMap;
class Profile;
class SiteEngagementObserver;
class SiteEngagementScore;

#if defined(OS_ANDROID)
class SiteEngagementServiceAndroid;
#endif

class SiteEngagementScoreProvider {
 public:
  // Returns a non-negative integer representing the engagement score of the
  // origin for this URL.
  virtual double GetScore(const GURL& url) const = 0;

  // Returns the sum of engagement points awarded to all sites.
  virtual double GetTotalEngagementPoints() const = 0;
};

// Stores and retrieves the engagement score of an origin.
//
// An engagement score is a non-negative double that represents how much a user
// has engaged with an origin - the higher it is, the more engagement the user
// has had with this site recently.
//
// User activity such as visiting the origin often, interacting with the origin,
// and adding it to the homescreen will increase the site engagement score. If
// a site's score does not increase for some time, it will decay, eventually
// reaching zero with further disuse.
//
// The SiteEngagementService object must be created and used on the UI thread
// only. Engagement scores may be queried in a read-only fashion from other
// threads using SiteEngagementService::GetScoreFromSettings, but use of this
// method is discouraged unless it is not possible to use the UI thread.
class SiteEngagementService : public KeyedService,
                              public history::HistoryServiceObserver,
                              public SiteEngagementScoreProvider {
 public:
  // This is used to back a UMA histogram, so it should be treated as
  // append-only. Any new values should be inserted immediately prior to
  // ENGAGEMENT_LAST and added to SiteEngagementServiceEngagementType in
  // tools/metrics/histograms/enums.xml.
  // TODO(calamity): Document each of these engagement types.
  enum EngagementType {
    ENGAGEMENT_NAVIGATION,
    ENGAGEMENT_KEYPRESS,
    ENGAGEMENT_MOUSE,
    ENGAGEMENT_TOUCH_GESTURE,
    ENGAGEMENT_SCROLL,
    ENGAGEMENT_MEDIA_HIDDEN,
    ENGAGEMENT_MEDIA_VISIBLE,
    ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH,
    ENGAGEMENT_FIRST_DAILY_ENGAGEMENT,
    ENGAGEMENT_NOTIFICATION_INTERACTION,
    ENGAGEMENT_LAST,
  };

  // WebContentsObserver that detects engagement triggering events and notifies
  // the service of them.
  class Helper;

  // The name of the site engagement variation field trial.
  static const char kEngagementParams[];

  // Returns the site engagement service attached to this profile. The service
  // exists in incognito mode; scores will be initialised using the score from
  // the profile that the incognito session was created from, and will increase
  // and decrease as usual. Engagement earned or decayed in incognito will not
  // be persisted or reflected in the original profile.
  //
  // This method must be called on the UI thread.
  static SiteEngagementService* Get(Profile* profile);

  // Returns the maximum possible amount of engagement that a site can accrue.
  static double GetMaxPoints();

  // Returns whether or not the site engagement service is enabled.
  static bool IsEnabled();

  // Returns the score for |origin| based on |settings|. Can be called on any
  // thread and does not cause any cleanup, decay, etc.
  //
  // Should only be used if you cannot create a SiteEngagementService (i.e. you
  // cannot run on the UI thread).
  static double GetScoreFromSettings(HostContentSettingsMap* settings,
                                     const GURL& origin);

  explicit SiteEngagementService(Profile* profile);
  ~SiteEngagementService() override;

  // KeyedService support:
  void Shutdown() override;

  // Returns the engagement level of |url|.
  blink::mojom::EngagementLevel GetEngagementLevel(const GURL& url) const;

  // Returns an array of engagement score details for all origins which have
  // a score, whether due to direct engagement, or other factors that cause
  // an engagement bonus to be applied.
  std::vector<mojom::SiteEngagementDetails> GetAllDetails() const;

  // Update the engagement score of |url| for a notification interaction.
  void HandleNotificationInteraction(const GURL& url);

  // Returns whether the engagement service has enough data to make meaningful
  // decisions. Clients should avoid using engagement in their heuristic until
  // this is true.
  bool IsBootstrapped() const;

  // Returns whether |url| has at least the given |level| of engagement.
  bool IsEngagementAtLeast(const GURL& url,
                           blink::mojom::EngagementLevel level) const;

  // Resets the base engagement for |url| to |score|, clearing daily limits. Any
  // bonus engagement that |url| has acquired is not affected by this method, so
  // the result of GetScore(|url|) may not be the same as |score|.
  void ResetBaseScoreForURL(const GURL& url, double score);

  // Update the last time |url| was opened from an installed shortcut (hosted in
  // |web_contents|) to be clock_->Now().
  void SetLastShortcutLaunchTime(content::WebContents* web_contents,
                                 const GURL& url);

  void HelperCreated(SiteEngagementService::Helper* helper);
  void HelperDeleted(SiteEngagementService::Helper* helper);

  // Returns the site engagement details for the specified |url|.
  mojom::SiteEngagementDetails GetDetails(const GURL& url) const;

  // Overridden from SiteEngagementScoreProvider.
  double GetScore(const GURL& url) const override;
  double GetTotalEngagementPoints() const override;

 private:
  friend class SiteEngagementObserver;
  friend class SiteEngagementServiceAndroid;
  friend class SiteEngagementServiceTest;
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CheckHistograms);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CleanupEngagementScores);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                           CleanupMovesScoreBackToNow);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                           CleanupMovesScoreBackToRebase);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                           CleanupEngagementScoresProportional);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetMedianEngagement);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalNavigationPoints);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalUserInputPoints);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                           GetTotalNotificationPoints);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, RestrictedToHTTPAndHTTPS);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, LastShortcutLaunch);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                           CleanupOriginsOnHistoryDeletion);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, IsBootstrapped);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, EngagementLevel);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, Observers);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ScoreDecayHistograms);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, LastEngagementTime);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest,
                           IncognitoEngagementService);
  FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetScoreFromSettings);
  FRIEND_TEST_ALL_PREFIXES(banners::AppBannerManagerBrowserTest,
                           CheckOnLoadWithoutSufficientEngagement);
  FRIEND_TEST_ALL_PREFIXES(AppBannerSettingsHelperTest, SiteEngagementTrigger);
  FRIEND_TEST_ALL_PREFIXES(HostedAppPWAOnlyTest, EngagementHistogram);

#if defined(OS_ANDROID)
  // Shim class to expose the service to Java.
  SiteEngagementServiceAndroid* GetAndroidService() const;
  void SetAndroidService(
      std::unique_ptr<SiteEngagementServiceAndroid> android_service);
#endif

  // Only used in tests.
  SiteEngagementService(Profile* profile, std::unique_ptr<base::Clock> clock);

  // Adds the specified number of points to the given origin, respecting the
  // maximum limits for the day and overall.
  void AddPoints(const GURL& url, double points);

  // Retrieves the SiteEngagementScore object for |origin|.
  SiteEngagementScore CreateEngagementScore(const GURL& origin) const;

  // Runs site engagement maintenance tasks.
  void AfterStartupTask();

  // Removes any origins which have decayed to 0 engagement. If
  // |update_last_engagement_time| is true, the last engagement time of all
  // origins is reset by calculating the delta between the last engagement event
  // recorded by the site engagement service and the origin. The origin's last
  // engagement time is then set to clock_->Now() - delta.
  //
  // If a user does not use the browser at all for some period of time,
  // engagement is not decayed, and the state is restored equivalent to how they
  // left it once they return.
  void CleanupEngagementScores(bool update_last_engagement_time) const;

  // Records UMA metrics.
  void RecordMetrics();

  // Returns true if we should record engagement for this URL. Currently,
  // engagement is only earned for HTTP and HTTPS.
  bool ShouldRecordEngagement(const GURL& url) const;

  // Get and set the last engagement time from prefs.
  base::Time GetLastEngagementTime() const;
  void SetLastEngagementTime(base::Time last_engagement_time) const;

  // Get the maximum decay period and the stale period for last engagement
  // times.
  base::TimeDelta GetMaxDecayPeriod() const;
  base::TimeDelta GetStalePeriod() const;

  // Returns the median engagement score of all recorded origins. |details| must
  // be sorted in ascending order of score.
  double GetMedianEngagementFromSortedDetails(
      const std::vector<mojom::SiteEngagementDetails>& details) const;

  // Update the engagement score of the origin loaded in |web_contents| for
  // media playing. The points awarded are discounted if the media is being
  // played in a non-visible tab.
  void HandleMediaPlaying(content::WebContents* web_contents, bool is_hidden);

  // Update the engagement score of the origin loaded in |web_contents| for
  // navigation.
  void HandleNavigation(content::WebContents* web_contents,
                        ui::PageTransition transition);

  // Update the engagement score of the origin loaded in |web_contents| for
  // time-on-site, based on user input.
  void HandleUserInput(content::WebContents* web_contents, EngagementType type);

  // Called when the engagement for |url| loaded in |web_contents| is changed,
  // due to an event of type |type|. Calls OnEngagementEvent in all observers.
  // |web_contents| may be null if the engagement has increased when |url| is
  // not in a tab, e.g. from a notification interaction. Also records
  // engagement-type metrics.
  void OnEngagementEvent(content::WebContents* web_contents,
                         const GURL& url,
                         EngagementType type);

  // Called if |url| changes to |level| engagement, and informs every Helper of
  // the change.
  void SendLevelChangeToHelpers(const GURL& url,
                                blink::mojom::EngagementLevel level);

  // Returns true if the last engagement increasing event seen by the site
  // engagement service was sufficiently long ago that we need to reset all
  // scores to be relative to now. This ensures that users who do not use the
  // browser for an extended period of time do not have their engagement decay.
  bool IsLastEngagementStale() const;

  // Overridden from history::HistoryServiceObserver:
  void OnURLsDeleted(history::HistoryService* history_service,
                     bool all_history,
                     bool expired,
                     const history::URLRows& deleted_rows,
                     const std::set<GURL>& favicon_urls) override;

  // Returns the number of origins with maximum daily and total engagement
  // respectively.
  int OriginsWithMaxDailyEngagement() const;
  int OriginsWithMaxEngagement(
      const std::vector<mojom::SiteEngagementDetails>& details) const;

  // Callback for the history service when it is asked for a map of origins to
  // how many URLs corresponding to that origin remain in history.
  void GetCountsAndLastVisitForOriginsComplete(
      history::HistoryService* history_service,
      const std::multiset<GURL>& deleted_url_origins,
      bool expired,
      const history::OriginCountAndLastVisitMap& remaining_origin_counts);

  // Add and remove observers of this service.
  void AddObserver(SiteEngagementObserver* observer);
  void RemoveObserver(SiteEngagementObserver* observer);

  Profile* profile_;

  // The clock used to vend times.
  std::unique_ptr<base::Clock> clock_;

#if defined(OS_ANDROID)
  std::unique_ptr<SiteEngagementServiceAndroid> android_service_;
#endif

  // Metrics are recorded at non-incognito browser startup, and then
  // approximately once per hour thereafter. Store the local time at which
  // metrics were previously uploaded: the first event which affects any
  // origin's engagement score after an hour has elapsed triggers the next
  // upload.
  base::Time last_metrics_time_;

  // All helpers currently attached to a WebContents.
  std::set<SiteEngagementService::Helper*> helpers_;

  // A list of observers. When any origin registers an engagement-increasing
  // event, each observer's OnEngagementEvent method will be called.
  base::ObserverList<SiteEngagementObserver> observer_list_;

  base::WeakPtrFactory<SiteEngagementService> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(SiteEngagementService);
};

#endif  // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_
