// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/promos/promos_utils.h"

#include <string>
#include <vector>

#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/json/values_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/promos/promos_pref_names.h"
#include "chrome/browser/promos/promos_types.h"
#include "chrome/common/pref_names.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/search/ntp_features.h"
#include "components/segmentation_platform/embedder/default_model/device_switcher_model.h"
#include "components/sync/base/data_type.h"
#include "components/sync/service/sync_service.h"

namespace promos_utils {

// Max impression count per user, per promo for the iOS desktop promos on
// desktop.
constexpr int kiOSDesktopPromoMaxImpressionCount = 3;

// Total impression count per user in their lifetime, for all iOS desktop
// promos.
constexpr int kiOSDesktopPromoTotalImpressionCount = 10;

// Total amount of opt-outs across any Desktop to iOS promo to block impressions
// of other instances of Desktop to iOS promos, per user.
constexpr int kiOSDesktopPromoTotalOptOuts = 2;

// Minimum time threshold between impressions for a given user to see the iOS
// desktop promo on desktop.
constexpr base::TimeDelta kiOSDesktopPromoCooldownTime = base::Days(90);

// IOSDesktopPromoHistogramType returns the promo histogram type for the given
// promo type. New promos should add themselves to this check.
std::string IOSDesktopPromoHistogramType(IOSPromoType promo_type) {
  switch (promo_type) {
    case IOSPromoType::kPassword:
      return "PasswordPromo";
    case IOSPromoType::kAddress:
      return "AddressPromo";
    case IOSPromoType::kPayment:
      return "PaymentPromo";
    case IOSPromoType::kEnhancedBrowsing:
      return "EnhancedBrowsingPromo";
    case IOSPromoType::kLens:
      return "LensPromo";
  }
}

base::Time GetMostRecentiOSDesktopNtpPromoTimestamp(PrefService* pref_service) {
  const base::Value::List& timestamps = pref_service->GetList(
      promos_prefs::kDesktopToiOSNtpPromoAppearanceTimestamps);
  base::Value::List::const_iterator most_recent_timestamp_iter =
      std::max_element(timestamps.begin(), timestamps.end());
  if (most_recent_timestamp_iter == timestamps.end()) {
    return base::Time();
  }
  return base::ValueToTime(*most_recent_timestamp_iter).value_or(base::Time());
}

// VerifyIOSDesktopPromoTotalImpressions ensures that each individual user sees
// no more than a maximum of these promos total in their lifetime. New promos
// should add themselves to this check. If `skip_ntp_promo` is true, then this
// call will not include ntp promo data in its checks. This allows calling code
// from the NTP promo to add special logic.
bool VerifyIOSDesktopPromoTotalImpressions(Profile* profile,
                                           bool skip_ntp_promo = false) {
  int total_desktop_promo_impressions =
      profile->GetPrefs()->GetInteger(
          promos_prefs::kDesktopToiOSPasswordPromoImpressionsCounter) +
      profile->GetPrefs()->GetInteger(
          promos_prefs::kDesktopToiOSAddressPromoImpressionsCounter) +
      profile->GetPrefs()->GetInteger(
          promos_prefs::kDesktopToiOSPaymentPromoImpressionsCounter) +
      profile->GetPrefs()->GetInteger(
          promos_prefs::kDesktopToiOSEnhancedBrowsingPromoImpressionsCounter) +
      profile->GetPrefs()->GetInteger(
          promos_prefs::kDesktopToiOSLensPromoImpressionsCounter);

  if (!skip_ntp_promo) {
    // The Desktop NTP promo shows 10 times in quick succession, but that only
    // counts as 1 impression for Desktop to iOS promos in general.
    const base::Value::List& ntp_promo_appearances =
        profile->GetPrefs()->GetList(
            promos_prefs::kDesktopToiOSNtpPromoAppearanceTimestamps);
    total_desktop_promo_impressions += (ntp_promo_appearances.empty()) ? 0 : 1;
  }

  return total_desktop_promo_impressions < kiOSDesktopPromoTotalImpressionCount;
}

// VerifyIOSDesktopPromoTotalOptOuts verifies that a user hasn't opted-out of
// seeing more than the allowed amount of opt-outs for all iOS Desktop promos.
// New promos should add themselves to this check.
bool VerifyIOSDesktopPromoTotalOptOuts(Profile* profile) {
  std::vector<bool> promo_opt_outs = {
      profile->GetPrefs()->GetBoolean(
          promos_prefs::kDesktopToiOSPasswordPromoOptOut),
      profile->GetPrefs()->GetBoolean(
          promos_prefs::kDesktopToiOSAddressPromoOptOut),
      profile->GetPrefs()->GetBoolean(
          promos_prefs::kDesktopToiOSPaymentPromoOptOut),
      profile->GetPrefs()->GetBoolean(
          promos_prefs::kDesktopToiOSEnhancedBrowsingPromoOptOut),
      profile->GetPrefs()->GetBoolean(
          promos_prefs::kDesktopToiOSLensPromoOptOut)};

  int total_desktop_promo_opt_outs_counter =
      std::count(promo_opt_outs.begin(), promo_opt_outs.end(), true);

  return total_desktop_promo_opt_outs_counter < kiOSDesktopPromoTotalOptOuts;
}

// VerifyMostRecentPromoTimestamp ensures that each individual user sees a
// Desktop to iOS promo a maximum of once per cooldown period. New promos should
// add themselves to this check. If `skip_ntp_promo` is true, then this call
// will not include ntp promo data in its checks. This allows calling code from
// the NTP promo to add special logic.
bool VerifyMostRecentPromoTimestamp(Profile* profile,
                                    bool skip_ntp_promo = false) {
  std::vector<base::Time> promos_timestamps = {
      profile->GetPrefs()->GetTime(
          promos_prefs::kDesktopToiOSPasswordPromoLastImpressionTimestamp),
      profile->GetPrefs()->GetTime(
          promos_prefs::kDesktopToiOSAddressPromoLastImpressionTimestamp),
      profile->GetPrefs()->GetTime(
          promos_prefs::kDesktopToiOSPaymentPromoLastImpressionTimestamp),
      profile->GetPrefs()->GetTime(
          promos_prefs::
              kDesktopToiOSEnhancedBrowsingPromoLastImpressionTimestamp),
      profile->GetPrefs()->GetTime(
          promos_prefs::kDesktopToiOSLensPromoLastImpressionTimestamp),
  };

  if (!skip_ntp_promo) {
    promos_timestamps.emplace_back(
        GetMostRecentiOSDesktopNtpPromoTimestamp(profile->GetPrefs()));
  }

  auto most_recent_promo_timestamp =
      std::max_element(promos_timestamps.begin(), promos_timestamps.end());

  return *most_recent_promo_timestamp + kiOSDesktopPromoCooldownTime <
         base::Time::Now();
}

// Verify that the user is syncing preferences (for impressions and opt-out
// tracking), and that they are syncing the specific datatype needed for a given
// promo type.
bool VerifySyncingDatatypes(const syncer::SyncService& sync_service,
                            IOSPromoType promo_type) {
  if (!sync_service.GetActiveDataTypes().Has(syncer::PREFERENCES)) {
    return false;
  }

  switch (promo_type) {
    case IOSPromoType::kPassword:
      return sync_service.GetActiveDataTypes().Has(syncer::PASSWORDS);
    case IOSPromoType::kAddress:
      return sync_service.GetActiveDataTypes().Has(syncer::CONTACT_INFO);
    case IOSPromoType::kPayment:
      return sync_service.GetActiveDataTypes().Has(
          syncer::AUTOFILL_WALLET_DATA);
    case IOSPromoType::kEnhancedBrowsing:
    case IOSPromoType::kLens:
      // TODO(crbug.com/438769954): Verify relevant data types.
      return true;
  }
}

// Checks whether promos in general can currently be shown.
bool CanShowPromos() {
// Don't show the promo if the local state exists and `kPromotionsEnabled` is
// false (likely overridden by policy). `kPromotionsEnabled` does not exist on
// Android.
#if !BUILDFLAG(IS_ANDROID)
  PrefService* local_state = g_browser_process->local_state();
  if (local_state && !local_state->GetBoolean(prefs::kPromotionsEnabled)) {
    return false;
  }
#endif  // !BUILDFLAG(IS_ANDROID)
  return true;
}

// RecordIOSDesktopPromoShownHistogram records which impression (count) was
// shown to the user depending on the given promo type.
void RecordIOSDesktopPromoShownHistogram(IOSPromoType promo_type,
                                         int impression_count) {
  std::string promo_histogram_type = IOSDesktopPromoHistogramType(promo_type);
  DesktopIOSPromoImpression promo_impression;
  switch (impression_count) {
    case 1:
      promo_impression = DesktopIOSPromoImpression::kFirstImpression;
      break;
    case 2:
      promo_impression = DesktopIOSPromoImpression::kSecondImpression;
      break;
    case 3:
      promo_impression = DesktopIOSPromoImpression::kThirdImpression;
      break;
    default:
      NOTREACHED();
  }
  base::UmaHistogramEnumeration(
      "IOS.Desktop." + promo_histogram_type + ".Shown", promo_impression);
}

// IOSPromoPrefsConfig is a complex struct that needs definition of a
// constructor, an explicit out-of-line copy constructor and a destructor. New
// promos should add themselves to this function.
IOSPromoPrefsConfig::IOSPromoPrefsConfig() = default;
IOSPromoPrefsConfig::IOSPromoPrefsConfig(const IOSPromoPrefsConfig&) = default;
IOSPromoPrefsConfig::~IOSPromoPrefsConfig() = default;

IOSPromoPrefsConfig::IOSPromoPrefsConfig(IOSPromoType promo_type) {
  switch (promo_type) {
    case IOSPromoType::kPassword:
#if !BUILDFLAG(IS_ANDROID)
      promo_feature = &feature_engagement::kIPHiOSPasswordPromoDesktopFeature;
#endif  // !BUILDFLAG(IS_ANDROID)
      promo_impressions_counter_pref_name =
          promos_prefs::kDesktopToiOSPasswordPromoImpressionsCounter;
      promo_opt_out_pref_name = promos_prefs::kDesktopToiOSPasswordPromoOptOut;
      promo_last_impression_timestamp_pref_name =
          promos_prefs::kDesktopToiOSPasswordPromoLastImpressionTimestamp;
      break;
    case IOSPromoType::kAddress:
#if !BUILDFLAG(IS_ANDROID)
      promo_feature = &feature_engagement::kIPHiOSAddressPromoDesktopFeature;
#endif  // !BUILDFLAG(IS_ANDROID)
      promo_impressions_counter_pref_name =
          promos_prefs::kDesktopToiOSAddressPromoImpressionsCounter;
      promo_opt_out_pref_name = promos_prefs::kDesktopToiOSAddressPromoOptOut;
      promo_last_impression_timestamp_pref_name =
          promos_prefs::kDesktopToiOSAddressPromoLastImpressionTimestamp;
      break;
    case IOSPromoType::kPayment:
#if !BUILDFLAG(IS_ANDROID)
      promo_feature = &feature_engagement::kIPHiOSPaymentPromoDesktopFeature;
#endif  // !BUILDFLAG(IS_ANDROID)
      promo_impressions_counter_pref_name =
          promos_prefs::kDesktopToiOSPaymentPromoImpressionsCounter;
      promo_opt_out_pref_name = promos_prefs::kDesktopToiOSPaymentPromoOptOut;
      promo_last_impression_timestamp_pref_name =
          promos_prefs::kDesktopToiOSPaymentPromoLastImpressionTimestamp;
      break;
    case IOSPromoType::kEnhancedBrowsing:
#if !BUILDFLAG(IS_ANDROID)
      promo_feature =
          &feature_engagement::kIPHiOSEnhancedBrowsingDesktopFeature;
#endif  // !BUILDFLAG(IS_ANDROID)
      promo_impressions_counter_pref_name =
          promos_prefs::kDesktopToiOSEnhancedBrowsingPromoImpressionsCounter;
      promo_opt_out_pref_name =
          promos_prefs::kDesktopToiOSEnhancedBrowsingPromoOptOut;
      promo_last_impression_timestamp_pref_name = promos_prefs::
          kDesktopToiOSEnhancedBrowsingPromoLastImpressionTimestamp;
      break;
    case IOSPromoType::kLens:
#if !BUILDFLAG(IS_ANDROID)
      promo_feature = &feature_engagement::kIPHiOSLensPromoDesktopFeature;
#endif  // !BUILDFLAG(IS_ANDROID)
      promo_impressions_counter_pref_name =
          promos_prefs::kDesktopToiOSLensPromoImpressionsCounter;
      promo_opt_out_pref_name = promos_prefs::kDesktopToiOSLensPromoOptOut;
      promo_last_impression_timestamp_pref_name =
          promos_prefs::kDesktopToiOSLensPromoLastImpressionTimestamp;
      break;
  }
}

// Registers profile prefs. New promos should add themselves to this function.
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterTimePref(
      promos_prefs::kDesktopToiOSPasswordPromoLastImpressionTimestamp,
      base::Time(), user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterIntegerPref(
      promos_prefs::kDesktopToiOSPasswordPromoImpressionsCounter, 0,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      promos_prefs::kDesktopToiOSPasswordPromoOptOut, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  registry->RegisterTimePref(
      promos_prefs::kDesktopToiOSAddressPromoLastImpressionTimestamp,
      base::Time(), user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterIntegerPref(
      promos_prefs::kDesktopToiOSAddressPromoImpressionsCounter, 0,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      promos_prefs::kDesktopToiOSAddressPromoOptOut, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  registry->RegisterTimePref(
      promos_prefs::kDesktopToiOSPaymentPromoLastImpressionTimestamp,
      base::Time(), user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterIntegerPref(
      promos_prefs::kDesktopToiOSPaymentPromoImpressionsCounter, 0,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      promos_prefs::kDesktopToiOSPaymentPromoOptOut, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  registry->RegisterTimePref(
      promos_prefs::kDesktopToiOSEnhancedBrowsingPromoLastImpressionTimestamp,
      base::Time(), user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterIntegerPref(
      promos_prefs::kDesktopToiOSEnhancedBrowsingPromoImpressionsCounter, 0,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      promos_prefs::kDesktopToiOSEnhancedBrowsingPromoOptOut, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  registry->RegisterTimePref(
      promos_prefs::kDesktopToiOSLensPromoLastImpressionTimestamp, base::Time(),
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterIntegerPref(
      promos_prefs::kDesktopToiOSLensPromoImpressionsCounter, 0,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      promos_prefs::kDesktopToiOSLensPromoOptOut, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  registry->RegisterListPref(
      promos_prefs::kDesktopToiOSNtpPromoAppearanceTimestamps, {},
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      promos_prefs::kDesktopToiOSNtpPromoDismissed, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
}

const base::Feature& GetIOSDesktopPromoFeatureEngagement(
    IOSPromoType promo_type) {
  IOSPromoPrefsConfig promo_prefs(promo_type);
  return *promo_prefs.promo_feature;
}

// RecordIOSDesktopPromoUserInteractionHistogram records which impression
// (count) depending on the promo type.
void RecordIOSDesktopPromoUserInteractionHistogram(
    IOSPromoType promo_type,
    int impression_count,
    DesktopIOSPromoAction action) {
  std::string promo_histogram_type = IOSDesktopPromoHistogramType(promo_type);
  if (impression_count == 1) {
    base::UmaHistogramEnumeration(
        "IOS.Desktop." + promo_histogram_type + ".FirstImpression.Action",
        action);
  } else if (impression_count == 2) {
    base::UmaHistogramEnumeration(
        "IOS.Desktop." + promo_histogram_type + ".SecondImpression.Action",
        action);
  } else if (impression_count == 3) {
    base::UmaHistogramEnumeration(
        "IOS.Desktop." + promo_histogram_type + ".ThirdImpression.Action",
        action);
  } else {
    NOTREACHED();
  }
}

bool ShouldShowIOSDesktopPromo(Profile* profile,
                               const syncer::SyncService* sync_service,
                               IOSPromoType promo_type) {
  if (!CanShowPromos()) {
    return false;
  }

  IOSPromoPrefsConfig promo_prefs(promo_type);

  // Show the promo if the user hasn't opted out, is not in the cooldown
  // period and is within the impression limit for this promo.
  return sync_service && VerifySyncingDatatypes(*sync_service, promo_type) &&
         profile->GetPrefs()->GetInteger(
             promo_prefs.promo_impressions_counter_pref_name) <
             kiOSDesktopPromoMaxImpressionCount &&
         VerifyMostRecentPromoTimestamp(profile) &&
         VerifyIOSDesktopPromoTotalImpressions(profile) &&
         VerifyIOSDesktopPromoTotalOptOuts(profile) &&
         !profile->GetPrefs()->GetBoolean(promo_prefs.promo_opt_out_pref_name);
}

bool ShouldShowIOSDesktopNtpPromo(Profile* profile,
                                  const syncer::SyncService* sync_service) {
  if (!CanShowPromos()) {
    return false;
  }

  PrefService* pref_service = profile->GetPrefs();

  // Sync must be active because prefs to track promo display are synced.
  bool sync_ok = sync_service &&
                 sync_service->GetActiveDataTypes().Has(syncer::PREFERENCES);

  // This promo can appear 10 times itself.
  int appearance_count =
      pref_service
          ->GetList(promos_prefs::kDesktopToiOSNtpPromoAppearanceTimestamps)
          .size();
  bool appearance_count_ok =
      appearance_count < ntp_features::kNtpMobilePromoImpressionLimit.Get();

  bool has_not_dismissed = !profile->GetPrefs()->GetBoolean(
      promos_prefs::kDesktopToiOSNtpPromoDismissed);

  bool other_promos_ok =
      VerifyMostRecentPromoTimestamp(profile, /*skip_ntp_promo=*/true) &&
      VerifyIOSDesktopPromoTotalImpressions(profile, /*skip_ntp_promo=*/true);

  // Show the promo if the user hasn't opted out, is not in the cooldown
  // period and is within the impression limit for this promo.
  return sync_ok && appearance_count_ok && has_not_dismissed && other_promos_ok;
}

bool UserNotClassifiedAsMobileDeviceSwitcher(
    const segmentation_platform::ClassificationResult& result) {
  return result.status == segmentation_platform::PredictionStatus::kSucceeded &&
         !base::Contains(
             result.ordered_labels,
             segmentation_platform::DeviceSwitcherModel::kAndroidPhoneLabel) &&
         !base::Contains(result.ordered_labels,
                         segmentation_platform::DeviceSwitcherModel::
                             kIosPhoneChromeLabel) &&
         !base::Contains(
             result.ordered_labels,
             segmentation_platform::DeviceSwitcherModel::kAndroidTabletLabel) &&
         !base::Contains(
             result.ordered_labels,
             segmentation_platform::DeviceSwitcherModel::kIosTabletLabel);
}

void IOSDesktopPromoShown(Profile* profile, IOSPromoType promo_type) {
  IOSPromoPrefsConfig promo_prefs(promo_type);
  int new_impression_count =
      profile->GetPrefs()->GetInteger(
          promo_prefs.promo_impressions_counter_pref_name) +
      1;

  profile->GetPrefs()->SetInteger(
      promo_prefs.promo_impressions_counter_pref_name, new_impression_count);
  profile->GetPrefs()->SetTime(
      promo_prefs.promo_last_impression_timestamp_pref_name, base::Time::Now());

  RecordIOSDesktopPromoShownHistogram(promo_type, new_impression_count);
}

void IOSDesktopNtpPromoShown(PrefService* pref_service) {
  ScopedListPrefUpdate update(
      pref_service, promos_prefs::kDesktopToiOSNtpPromoAppearanceTimestamps);
  update->Append(base::TimeToValue(base::Time::Now()));
}

}  // namespace promos_utils
