// Copyright 2014 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 "chromeos/timezone/timezone_resolver.h"

#include <math.h>
#include <stdint.h>

#include <algorithm>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_observer.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chromeos/geolocation/geoposition.h"
#include "chromeos/geolocation/simple_geolocation_provider.h"
#include "chromeos/timezone/timezone_provider.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

namespace chromeos {

namespace {

class TZRequest;

// Total timezone resolving process timeout.
const unsigned int kRefreshTimeZoneTimeoutSeconds = 60;

// Initial delay (for the first request).
const double kInitialRefreshIntervalSec = 3.0;

// Timezone refresh happens at least once each this interval.
const double kMaximumRefreshIntervalSec = 6.0 * 3600;  // 6 hours

// Delay between refresh attempts depends on current number of requests and
// this constant.
// [interval = kInitialRefreshIntervalMS * (2 ^
//                 (kRefreshIntervalRequestsCountMultiplier * requests_count))]
// in seconds.
// request_number interval (seconds)
// 1 3    (initial, requests_count = 0)
// 2 24   (requests_count = 1)
// 3 1536 (requests_count = 2)
// 4 12288 (requests_count = 3)
// 5+ 21600 (maximum)
const unsigned int kRefreshIntervalRequestsCountMultiplier = 3;

// We should limit request rate on browser start to prevent server overload
// on permanent browser crash.
// If too little time has passed since previous request, initialize
// |requests_count_| with |kRefreshTimeZoneInitialRequestCountOnRateLimit|.
const double kRefreshTimeZoneMinimumDelayOnRestartSec =
    10 * 60.0;  // 10 minutes
const unsigned int kRefreshTimeZoneInitialRequestCountOnRateLimit = 2;

int MaxRequestsCountForInterval(const double interval_seconds) {
  return log2(interval_seconds / kInitialRefreshIntervalSec) /
         kRefreshIntervalRequestsCountMultiplier;
}

int IntervalForNextRequest(const int requests) {
  const base::TimeDelta initial_interval =
      base::TimeDelta::FromSecondsD(kInitialRefreshIntervalSec);
  return static_cast<int>(initial_interval.InSecondsF() *
                          (2 << (static_cast<unsigned>(requests) *
                                 kRefreshIntervalRequestsCountMultiplier)));
}

}  // anonymous namespace

const char TimeZoneResolver::kLastTimeZoneRefreshTime[] =
    "timezone_resolver.last_update_time";

// This class periodically refreshes location and timezone.
// It should be destroyed to stop refresh.
class TimeZoneResolver::TimeZoneResolverImpl : public base::PowerObserver {
 public:
  explicit TimeZoneResolverImpl(const TimeZoneResolver* resolver);

  ~TimeZoneResolverImpl() override;

  // This is called once after the object is created.
  void Start();

  // PowerObserver implementation.
  void OnResume() override;

  // (Re)Starts timer.
  void ScheduleRequest();

  // Creates new TZRequest.
  void CreateNewRequest();

  // Called by TZRequest.
  SimpleGeolocationProvider* geolocation_provider() {
    return &geolocation_provider_;
  }
  TimeZoneProvider* timezone_provider() { return &timezone_provider_; }

  // Update requests count and last request time.
  void RecordAttempt();

  // This is called by TZRequest. Destroys active request and starts a new one.
  void RequestIsFinished();

  void ApplyTimeZone(const TimeZoneResponseData* timezone);

  TimeZoneResolver::DelayNetworkCallClosure delay_network_call() const {
    return resolver_->delay_network_call();
  }

  base::WeakPtr<TimeZoneResolver::TimeZoneResolverImpl> AsWeakPtr();

  bool ShouldSendWiFiGeolocationData();
  bool ShouldSendCellularGeolocationData();

 private:
  const TimeZoneResolver* resolver_;

  // Helper to check timezone detection policy against expected value
  bool CheckTimezoneManagementSetting(int expected_policy_value);

  // Returns delay to next timezone update request
  base::TimeDelta CalculateNextInterval();

  SimpleGeolocationProvider geolocation_provider_;
  TimeZoneProvider timezone_provider_;

  base::OneShotTimer refresh_timer_;

  // Total number of request attempts.
  int requests_count_;

  // This is not NULL when update is in progress.
  std::unique_ptr<TZRequest> request_;

  base::WeakPtrFactory<TimeZoneResolver::TimeZoneResolverImpl>
      weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(TimeZoneResolverImpl);
};

namespace {

// This class implements a single timezone refresh attempt.
class TZRequest {
 public:
  explicit TZRequest(TimeZoneResolver::TimeZoneResolverImpl* resolver)
      : resolver_(resolver), weak_ptr_factory_(this) {}

  ~TZRequest();

  // Starts request after specified delay.
  void Start();

  // Called from SimpleGeolocationProvider when location is resolved.
  void OnLocationResolved(const Geoposition& position,
                          bool server_error,
                          const base::TimeDelta elapsed);

  // TimeZoneRequest::TimeZoneResponseCallback implementation.
  void OnTimezoneResolved(std::unique_ptr<TimeZoneResponseData> timezone,
                          bool server_error);

  base::WeakPtr<TZRequest> AsWeakPtr();

 private:
  // This is called by network detector when network is available.
  void StartRequestOnNetworkAvailable();

  TimeZoneResolver::TimeZoneResolverImpl* const resolver_;

  base::WeakPtrFactory<TZRequest> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(TZRequest);
};

TZRequest::~TZRequest() = default;

void TZRequest::StartRequestOnNetworkAvailable() {
  resolver_->RecordAttempt();
  resolver_->geolocation_provider()->RequestGeolocation(
      base::TimeDelta::FromSeconds(kRefreshTimeZoneTimeoutSeconds),
      resolver_->ShouldSendWiFiGeolocationData(),
      resolver_->ShouldSendCellularGeolocationData(),
      base::Bind(&TZRequest::OnLocationResolved, AsWeakPtr()));
}

void TZRequest::Start() {
  // call to chromeos::DelayNetworkCall
  resolver_->delay_network_call().Run(
      base::Bind(&TZRequest::StartRequestOnNetworkAvailable, AsWeakPtr()));
}

void TZRequest::OnLocationResolved(const Geoposition& position,
                                   bool server_error,
                                   const base::TimeDelta elapsed) {
  base::ScopedClosureRunner on_request_finished(
      base::BindOnce(&TimeZoneResolver::TimeZoneResolverImpl::RequestIsFinished,
                     base::Unretained(resolver_)));

  // Ignore invalid position.
  if (!position.Valid())
    return;

  const base::TimeDelta timeout =
      base::TimeDelta::FromSeconds(kRefreshTimeZoneTimeoutSeconds);

  if (elapsed >= timeout) {
    VLOG(1) << "Refresh TimeZone: got location after timeout ("
            << elapsed.InSecondsF() << " seconds elapsed). Ignored.";
    return;
  }

  resolver_->timezone_provider()->RequestTimezone(
      position,
      timeout - elapsed,
      base::Bind(&TZRequest::OnTimezoneResolved, AsWeakPtr()));

  // Prevent |on_request_finished| from firing here.
  base::OnceClosure unused = on_request_finished.Release();
}

void TZRequest::OnTimezoneResolved(
    std::unique_ptr<TimeZoneResponseData> timezone,
    bool server_error) {
  base::ScopedClosureRunner on_request_finished(
      base::BindOnce(&TimeZoneResolver::TimeZoneResolverImpl::RequestIsFinished,
                     base::Unretained(resolver_)));

  DCHECK(timezone);
  VLOG(1) << "Refreshed local timezone={" << timezone->ToStringForDebug()
          << "}.";

  if (timezone->status != TimeZoneResponseData::OK) {
    VLOG(1) << "Refresh TimeZone: failed to resolve timezone.";
    return;
  }

  resolver_->ApplyTimeZone(timezone.get());
}

base::WeakPtr<TZRequest> TZRequest::AsWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

}  // anonymous namespace

// ------------------------------------------------------------------------
// TimeZoneResolver::TimeZoneResolverImpl implementation.

TimeZoneResolver::TimeZoneResolverImpl::TimeZoneResolverImpl(
    const TimeZoneResolver* resolver)
    : resolver_(resolver),
      geolocation_provider_(
          resolver->shared_url_loader_factory(),
          SimpleGeolocationProvider::DefaultGeolocationProviderURL()),
      timezone_provider_(resolver->shared_url_loader_factory(),
                         DefaultTimezoneProviderURL()),
      requests_count_(0),
      weak_ptr_factory_(this) {
  DCHECK(!resolver_->apply_timezone().is_null());
  DCHECK(!resolver_->delay_network_call().is_null());

  base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
  power_monitor->AddObserver(this);

  const int64_t last_refresh_at_raw =
      resolver_->local_state()->GetInt64(kLastTimeZoneRefreshTime);
  const base::Time last_refresh_at =
      base::Time::FromInternalValue(last_refresh_at_raw);
  const base::Time next_refresh_not_before =
      last_refresh_at +
      base::TimeDelta::FromSecondsD(kRefreshTimeZoneMinimumDelayOnRestartSec);
  if (next_refresh_not_before > base::Time::Now()) {
    requests_count_ = kRefreshTimeZoneInitialRequestCountOnRateLimit;
    VLOG(1) << "TimeZoneResolverImpl(): initialize requests_count_="
            << requests_count_ << " because of rate limit.";
  }
}

TimeZoneResolver::TimeZoneResolverImpl::~TimeZoneResolverImpl() {
  base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
  if (power_monitor)
    power_monitor->RemoveObserver(this);
}

void TimeZoneResolver::TimeZoneResolverImpl::Start() {
  // Start() is usually called twice:
  // - On device boot.
  // - On user session start.
  if (request_ || refresh_timer_.IsRunning())
    return;

  ScheduleRequest();
}

// Returns delay to next timezone update request
base::TimeDelta
TimeZoneResolver::TimeZoneResolverImpl::CalculateNextInterval() {
  // This is initial request, which should be served immediately.
  if (requests_count_ == 0) {
    return base::TimeDelta::FromSecondsD(kInitialRefreshIntervalSec);
  }

  // See comment to kRefreshIntervalRequestsCountMultiplier.
  if (requests_count_ >=
      MaxRequestsCountForInterval(kMaximumRefreshIntervalSec)) {
    return base::TimeDelta::FromSecondsD(kMaximumRefreshIntervalSec);
  }

  const int base_interval = IntervalForNextRequest(requests_count_);
  DCHECK_LE(base_interval, kMaximumRefreshIntervalSec);

  // Add jitter to level request rate.
  const base::TimeDelta interval(
      base::TimeDelta::FromSecondsD(base::RandDouble() * 2 * base_interval));
  VLOG(1) << "TimeZoneResolverImpl::CalculateNextInterval(): interval="
          << interval.InSecondsF();
  return interval;
}

void TimeZoneResolver::TimeZoneResolverImpl::OnResume() {
  requests_count_ = 0;
  // Refresh timezone immediately.
  request_.reset();
  ScheduleRequest();
}

void TimeZoneResolver::TimeZoneResolverImpl::ScheduleRequest() {
  if (request_)
    return;

  // base::OneShotTimer
  base::TimeDelta interval = CalculateNextInterval();
  refresh_timer_.Stop();
  refresh_timer_.Start(
      FROM_HERE, interval,
      base::Bind(&TimeZoneResolver::TimeZoneResolverImpl::CreateNewRequest,
                 AsWeakPtr()));
}

void TimeZoneResolver::TimeZoneResolverImpl::CreateNewRequest() {
  if (request_)
    return;

  refresh_timer_.Stop();

  request_.reset(new TZRequest(this));
  request_->Start();
}

void TimeZoneResolver::TimeZoneResolverImpl::RecordAttempt() {
  resolver_->local_state()->SetInt64(kLastTimeZoneRefreshTime,
                                     base::Time::Now().ToInternalValue());
  ++requests_count_;
}

void TimeZoneResolver::TimeZoneResolverImpl::RequestIsFinished() {
  request_.reset();
  ScheduleRequest();
}

void TimeZoneResolver::TimeZoneResolverImpl::ApplyTimeZone(
    const TimeZoneResponseData* timezone) {
  resolver_->apply_timezone().Run(timezone);
}

bool TimeZoneResolver::TimeZoneResolverImpl::ShouldSendWiFiGeolocationData() {
  return resolver_->ShouldSendWiFiGeolocationData();
}

bool TimeZoneResolver::TimeZoneResolverImpl::
    ShouldSendCellularGeolocationData() {
  return resolver_->ShouldSendCellularGeolocationData();
}

base::WeakPtr<TimeZoneResolver::TimeZoneResolverImpl>
TimeZoneResolver::TimeZoneResolverImpl::AsWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

// ------------------------------------------------------------------------
// TimeZoneResolver::Delegate implementation
TimeZoneResolver::Delegate::Delegate() = default;
TimeZoneResolver::Delegate::~Delegate() = default;

// ------------------------------------------------------------------------
// TimeZoneResolver implementation

TimeZoneResolver::TimeZoneResolver(
    Delegate* delegate,
    scoped_refptr<network::SharedURLLoaderFactory> factory,
    const GURL& url,
    const ApplyTimeZoneCallback& apply_timezone,
    const DelayNetworkCallClosure& delay_network_call,
    PrefService* local_state)
    : delegate_(delegate),
      shared_url_loader_factory_(std::move(factory)),
      url_(url),
      apply_timezone_(apply_timezone),
      delay_network_call_(delay_network_call),
      local_state_(local_state) {
  DCHECK(!apply_timezone.is_null());
  DCHECK(delegate_);
}

TimeZoneResolver::~TimeZoneResolver() {
  Stop();
}

void TimeZoneResolver::Start() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!implementation_) {
    implementation_.reset(new TimeZoneResolverImpl(this));
    implementation_->Start();
  }
}

void TimeZoneResolver::Stop() {
  DCHECK(thread_checker_.CalledOnValidThread());
  implementation_.reset();
}

// static
int TimeZoneResolver::MaxRequestsCountForIntervalForTesting(
    const double interval_seconds) {
  return MaxRequestsCountForInterval(interval_seconds);
}

// static
int TimeZoneResolver::IntervalForNextRequestForTesting(const int requests) {
  return IntervalForNextRequest(requests);
}

// static
void TimeZoneResolver::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterInt64Pref(kLastTimeZoneRefreshTime, 0);
}

bool TimeZoneResolver::ShouldSendWiFiGeolocationData() const {
  return delegate_->ShouldSendWiFiGeolocationData();
}

bool TimeZoneResolver::ShouldSendCellularGeolocationData() const {
  return delegate_->ShouldSendCellularGeolocationData();
}

scoped_refptr<network::SharedURLLoaderFactory>
TimeZoneResolver::shared_url_loader_factory() const {
  return shared_url_loader_factory_;
}

}  // namespace chromeos
