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

#include "components/metrics/data_use_tracker.h"

#include <string>

#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/variations/variations_associated_data.h"

namespace metrics {

namespace {

// Default weekly quota and allowed UMA ratio for UMA log uploads for Android.
// These defaults will not be used for non-Android as |DataUseTracker| will not
// be initialized. Default values can be overridden by variation params.
const int kDefaultUMAWeeklyQuotaBytes = 204800;
const double kDefaultUMARatio = 0.05;

}  // namespace

DataUseTracker::DataUseTracker(PrefService* local_state)
    : local_state_(local_state) {}

DataUseTracker::~DataUseTracker() {}

// static
std::unique_ptr<DataUseTracker> DataUseTracker::Create(
    PrefService* local_state) {
  std::unique_ptr<DataUseTracker> data_use_tracker;
#if defined(OS_ANDROID)
  data_use_tracker.reset(new DataUseTracker(local_state));
#endif
  return data_use_tracker;
}

// static
void DataUseTracker::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterDictionaryPref(metrics::prefs::kUserCellDataUse);
  registry->RegisterDictionaryPref(metrics::prefs::kUmaCellDataUse);
}

void DataUseTracker::UpdateMetricsUsagePrefs(const std::string& service_name,
                                             int message_size,
                                             bool is_cellular) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (!is_cellular)
    return;

  UpdateUsagePref(prefs::kUserCellDataUse, message_size);
  // TODO(holte): Consider adding seperate tracking for UKM.
  if (service_name == "UMA" || service_name == "UKM")
    UpdateUsagePref(prefs::kUmaCellDataUse, message_size);
}

bool DataUseTracker::ShouldUploadLogOnCellular(int log_bytes) {
  DCHECK(thread_checker_.CalledOnValidThread());

  RemoveExpiredEntries();

  int uma_weekly_quota_bytes;
  if (!GetUmaWeeklyQuota(&uma_weekly_quota_bytes))
    return true;

  int uma_total_data_use = ComputeTotalDataUse(prefs::kUmaCellDataUse);
  int new_uma_total_data_use = log_bytes + uma_total_data_use;
  // If the new log doesn't increase the total UMA traffic to be above the
  // allowed quota then the log should be uploaded.
  if (new_uma_total_data_use <= uma_weekly_quota_bytes)
    return true;

  double uma_ratio;
  if (!GetUmaRatio(&uma_ratio))
    return true;

  int user_total_data_use = ComputeTotalDataUse(prefs::kUserCellDataUse);
  // If after adding the new log the uma ratio is still under the allowed ratio
  // then the log should be uploaded and vice versa.
  return new_uma_total_data_use /
             static_cast<double>(log_bytes + user_total_data_use) <=
         uma_ratio;
}

void DataUseTracker::UpdateUsagePref(const std::string& pref_name,
                                     int message_size) {
  DCHECK(thread_checker_.CalledOnValidThread());

  DictionaryPrefUpdate pref_updater(local_state_, pref_name);
  int todays_traffic = 0;
  std::string todays_key = GetCurrentMeasurementDateAsString();

  const base::DictionaryValue* user_pref_dict =
      local_state_->GetDictionary(pref_name);
  user_pref_dict->GetInteger(todays_key, &todays_traffic);
  pref_updater->SetInteger(todays_key, todays_traffic + message_size);
}

void DataUseTracker::RemoveExpiredEntries() {
  DCHECK(thread_checker_.CalledOnValidThread());
  RemoveExpiredEntriesForPref(prefs::kUmaCellDataUse);
  RemoveExpiredEntriesForPref(prefs::kUserCellDataUse);
}

void DataUseTracker::RemoveExpiredEntriesForPref(const std::string& pref_name) {
  DCHECK(thread_checker_.CalledOnValidThread());

  const base::DictionaryValue* user_pref_dict =
      local_state_->GetDictionary(pref_name);
  const base::Time current_date = GetCurrentMeasurementDate();
  const base::Time week_ago = current_date - base::TimeDelta::FromDays(7);

  base::DictionaryValue user_pref_new_dict;
  for (base::DictionaryValue::Iterator it(*user_pref_dict); !it.IsAtEnd();
       it.Advance()) {
    base::Time key_date;
    if (base::Time::FromUTCString(it.key().c_str(), &key_date) &&
        key_date > week_ago)
      user_pref_new_dict.Set(it.key(), it.value().CreateDeepCopy());
  }
  local_state_->Set(pref_name, user_pref_new_dict);
}

// Note: We compute total data use regardless of what is the current date. In
// scenario when user travels back in time zone and current date becomes earlier
// than latest registered date in perf, we still count that in total use as user
// actually used that data.
int DataUseTracker::ComputeTotalDataUse(const std::string& pref_name) {
  DCHECK(thread_checker_.CalledOnValidThread());

  int total_data_use = 0;
  const base::DictionaryValue* pref_dict =
      local_state_->GetDictionary(pref_name);
  for (base::DictionaryValue::Iterator it(*pref_dict); !it.IsAtEnd();
       it.Advance()) {
    int value = 0;
    it.value().GetAsInteger(&value);
    total_data_use += value;
  }
  return total_data_use;
}

bool DataUseTracker::GetUmaWeeklyQuota(int* uma_weekly_quota_bytes) const {
  DCHECK(thread_checker_.CalledOnValidThread());

  std::string param_value_str = variations::GetVariationParamValue(
      "UMA_EnableCellularLogUpload", "Uma_Quota");
  if (param_value_str.empty())
    *uma_weekly_quota_bytes = kDefaultUMAWeeklyQuotaBytes;
  else
    base::StringToInt(param_value_str, uma_weekly_quota_bytes);
  return true;
}

bool DataUseTracker::GetUmaRatio(double* ratio) const {
  DCHECK(thread_checker_.CalledOnValidThread());

  std::string param_value_str = variations::GetVariationParamValue(
      "UMA_EnableCellularLogUpload", "Uma_Ratio");
  if (param_value_str.empty())
    *ratio = kDefaultUMARatio;
  else
    base::StringToDouble(param_value_str, ratio);
  return true;
}

base::Time DataUseTracker::GetCurrentMeasurementDate() const {
  return base::Time::Now().LocalMidnight();
}

std::string DataUseTracker::GetCurrentMeasurementDateAsString() const {
  DCHECK(thread_checker_.CalledOnValidThread());

  base::Time::Exploded today_exploded;
  GetCurrentMeasurementDate().LocalExplode(&today_exploded);
  return base::StringPrintf("%04d-%02d-%02d", today_exploded.year,
                            today_exploded.month, today_exploded.day_of_month);
}

}  // namespace metrics
