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

#include "components/signin/core/browser/child_account_info_fetcher_impl.h"

#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "components/invalidation/public/invalidation_service.h"
#include "components/invalidation/public/object_id_invalidation_map.h"
#include "components/signin/core/browser/account_fetcher_service.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "google/cacheinvalidation/types.pb.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_constants.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

// TODO(maroun): Remove this file.

namespace {

const char kFetcherId[] = "ChildAccountInfoFetcherImpl";

// Exponential backoff policy on service flag fetching failure.
const net::BackoffEntry::Policy kBackoffPolicy = {
  0,  // Number of initial errors to ignore without backoff.
  2000,  // Initial delay for backoff in ms.
  2,  // Factor to multiply waiting time by.
  0.2,  // Fuzzing percentage. 20% will spread requests randomly between
        // 80-100% of the calculated time.
  1000 * 60 * 60* 4,  // Maximum time to delay requests by (4 hours).
  -1,  // Don't discard entry even if unused.
  false,  // Don't use the initial delay unless the last request was an error.
};

// The invalidation object ID used for child account graduation event.
// The syntax is:
// 'U' -> This is a user specific invalidation.
// 'CA' -> Namespace used for all ChildAccount invalidations.
// 'GRAD' -> Indicates the actual event i.e. child account graduation.
const char kChildAccountGraduationId[] = "UCAGRAD";

}  // namespace

ChildAccountInfoFetcherImpl::ChildAccountInfoFetcherImpl(
    const std::string& account_id,
    AccountFetcherService* fetcher_service,
    OAuth2TokenService* token_service,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    invalidation::InvalidationService* invalidation_service)
    : OAuth2TokenService::Consumer(kFetcherId),
      token_service_(token_service),
      url_loader_factory_(url_loader_factory),
      fetcher_service_(fetcher_service),
      invalidation_service_(invalidation_service),
      account_id_(account_id),
      backoff_(&kBackoffPolicy),
      fetch_in_progress_(false) {
  TRACE_EVENT_ASYNC_BEGIN1("AccountFetcherService", kFetcherId, this,
                           "account_id", account_id);
  // Invalidation service may not be available in tests.
  if (invalidation_service_) {
    invalidation_service_->RegisterInvalidationHandler(this);
    syncer::ObjectIdSet ids;
    ids.insert(invalidation::ObjectId(
        ipc::invalidation::ObjectSource::CHROME_COMPONENTS,
        kChildAccountGraduationId));
    bool insert_success =
        invalidation_service_->UpdateRegisteredInvalidationIds(this, ids);
    DCHECK(insert_success);
  }
  FetchIfNotInProgress();
}

ChildAccountInfoFetcherImpl::~ChildAccountInfoFetcherImpl() {
  TRACE_EVENT_ASYNC_END0("AccountFetcherService", kFetcherId, this);
  if (invalidation_service_)
    UnregisterInvalidationHandler();
}

void ChildAccountInfoFetcherImpl::FetchIfNotInProgress() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (fetch_in_progress_)
    return;
  fetch_in_progress_ = true;
  OAuth2TokenService::ScopeSet scopes;
  scopes.insert(GaiaConstants::kOAuth1LoginScope);
  login_token_request_ =
      token_service_->StartRequest(account_id_, scopes, this);
}

void ChildAccountInfoFetcherImpl::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const std::string& access_token,
    const base::Time& expiration_time) {
  TRACE_EVENT_ASYNC_STEP_PAST0("AccountFetcherService", kFetcherId, this,
                               "OnGetTokenSuccess");
  DCHECK_EQ(request, login_token_request_.get());

  gaia_auth_fetcher_ = fetcher_service_->signin_client_->CreateGaiaAuthFetcher(
      this, GaiaConstants::kChromeSource, url_loader_factory_);
  gaia_auth_fetcher_->StartOAuthLogin(access_token,
                                      GaiaConstants::kGaiaService);
}

void ChildAccountInfoFetcherImpl::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  HandleFailure();
}

void ChildAccountInfoFetcherImpl::OnClientLoginSuccess(
    const ClientLoginResult& result) {
  gaia_auth_fetcher_->StartGetUserInfo(result.lsid);
}

void ChildAccountInfoFetcherImpl::OnClientLoginFailure(
    const GoogleServiceAuthError& error) {
  HandleFailure();
}

void ChildAccountInfoFetcherImpl::OnGetUserInfoSuccess(
    const UserInfoMap& data) {
  UserInfoMap::const_iterator services_iter = data.find("allServices");
  if (services_iter != data.end()) {
    std::vector<std::string> service_flags = base::SplitString(
        services_iter->second, ",", base::TRIM_WHITESPACE,
        base::SPLIT_WANT_ALL);
    bool is_child_account = base::ContainsValue(
        service_flags, AccountTrackerService::kChildAccountServiceFlag);
    if (!is_child_account && invalidation_service_) {
      // Don't bother listening for invalidations as a non-child account can't
      // become a child account.
      bool insert_success =
          invalidation_service_->UpdateRegisteredInvalidationIds(
              this, syncer::ObjectIdSet());
      DCHECK(insert_success);
      UnregisterInvalidationHandler();
    }
    fetcher_service_->SetIsChildAccount(account_id_, is_child_account);
  } else {
    DLOG(ERROR) << "ChildAccountInfoFetcherImpl::OnGetUserInfoSuccess: "
                << "GetUserInfo response didn't include allServices field.";
  }
  fetch_in_progress_ = false;
}

void ChildAccountInfoFetcherImpl::OnGetUserInfoFailure(
    const GoogleServiceAuthError& error) {
  HandleFailure();
}

void ChildAccountInfoFetcherImpl::HandleFailure() {
  fetch_in_progress_ = false;
  backoff_.InformOfRequest(false);
  timer_.Start(FROM_HERE, backoff_.GetTimeUntilRelease(), this,
               &ChildAccountInfoFetcherImpl::FetchIfNotInProgress);
}

void ChildAccountInfoFetcherImpl::UnregisterInvalidationHandler() {
  invalidation_service_->UnregisterInvalidationHandler(this);
  invalidation_service_ = nullptr;
}

void ChildAccountInfoFetcherImpl::OnInvalidatorStateChange(
    syncer::InvalidatorState state) {
  if (state == syncer::INVALIDATOR_SHUTTING_DOWN)
    UnregisterInvalidationHandler();
}

void ChildAccountInfoFetcherImpl::OnIncomingInvalidation(
    const syncer::ObjectIdInvalidationMap& invalidation_map) {
  FetchIfNotInProgress();
  invalidation_map.AcknowledgeAll();
}

std::string ChildAccountInfoFetcherImpl::GetOwnerName() const {
  return std::string(kFetcherId);
}
