// Copyright (c) 2013 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/gcm_driver/gcm_profile_service.h"

#include <utility>
#include <vector>

#include "base/logging.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/gcm_driver/gcm_driver_constants.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"

#if BUILDFLAG(USE_GCM_FROM_PLATFORM)
#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_worker_pool.h"
#include "components/gcm_driver/gcm_driver_android.h"
#else
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "components/gcm_driver/gcm_account_tracker.h"
#include "components/gcm_driver/gcm_channel_status_syncer.h"
#include "components/gcm_driver/gcm_client_factory.h"
#include "components/gcm_driver/gcm_desktop_utils.h"
#include "components/gcm_driver/gcm_driver_desktop.h"
#include "components/signin/core/browser/signin_manager.h"
#include "google_apis/gaia/account_tracker.h"
#include "google_apis/gaia/identity_provider.h"
#include "net/url_request/url_request_context_getter.h"
#endif

namespace gcm {

#if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
// Identity observer only has actual work to do when the user is actually signed
// in. It ensures that account tracker is taking
class GCMProfileService::IdentityObserver : public IdentityProvider::Observer {
 public:
  IdentityObserver(ProfileIdentityProvider* identity_provider,
                   net::URLRequestContextGetter* request_context,
                   GCMDriver* driver);
  ~IdentityObserver() override;

  // IdentityProvider::Observer:
  void OnActiveAccountLogin() override;
  void OnActiveAccountLogout() override;

 private:
  void StartAccountTracker(net::URLRequestContextGetter* request_context);

  GCMDriver* driver_;
  IdentityProvider* identity_provider_;
  std::unique_ptr<GCMAccountTracker> gcm_account_tracker_;

  // The account ID that this service is responsible for. Empty when the service
  // is not running.
  std::string account_id_;

  base::WeakPtrFactory<GCMProfileService::IdentityObserver> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(IdentityObserver);
};

GCMProfileService::IdentityObserver::IdentityObserver(
    ProfileIdentityProvider* identity_provider,
    net::URLRequestContextGetter* request_context,
    GCMDriver* driver)
    : driver_(driver),
      identity_provider_(identity_provider),
      weak_ptr_factory_(this) {
  identity_provider_->AddObserver(this);

  OnActiveAccountLogin();
  StartAccountTracker(request_context);
}

GCMProfileService::IdentityObserver::~IdentityObserver() {
  if (gcm_account_tracker_)
    gcm_account_tracker_->Shutdown();
  identity_provider_->RemoveObserver(this);
}

void GCMProfileService::IdentityObserver::OnActiveAccountLogin() {
  // This might be called multiple times when the password changes.
  const std::string account_id = identity_provider_->GetActiveAccountId();
  if (account_id == account_id_)
    return;
  account_id_ = account_id;

  // Still need to notify GCMDriver for UMA purpose.
  driver_->OnSignedIn();
}

void GCMProfileService::IdentityObserver::OnActiveAccountLogout() {
  account_id_.clear();

  // Still need to notify GCMDriver for UMA purpose.
  driver_->OnSignedOut();
}

void GCMProfileService::IdentityObserver::StartAccountTracker(
    net::URLRequestContextGetter* request_context) {
  if (gcm_account_tracker_)
    return;

  std::unique_ptr<gaia::AccountTracker> gaia_account_tracker(
      new gaia::AccountTracker(identity_provider_, request_context));

  gcm_account_tracker_.reset(
      new GCMAccountTracker(std::move(gaia_account_tracker), driver_));

  gcm_account_tracker_->Start();
}

#endif  // !BUILDFLAG(USE_GCM_FROM_PLATFORM)

// static
bool GCMProfileService::IsGCMEnabled(PrefService* prefs) {
#if BUILDFLAG(USE_GCM_FROM_PLATFORM)
  return true;
#else
  return prefs->GetBoolean(gcm::prefs::kGCMChannelStatus);
#endif  // BUILDFLAG(USE_GCM_FROM_PLATFORM)
}

#if BUILDFLAG(USE_GCM_FROM_PLATFORM)
GCMProfileService::GCMProfileService(
    base::FilePath path,
    scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) {
  driver_.reset(new GCMDriverAndroid(path.Append(gcm_driver::kGCMStoreDirname),
                                     blocking_task_runner));
}
#else
GCMProfileService::GCMProfileService(
    PrefService* prefs,
    base::FilePath path,
    net::URLRequestContextGetter* request_context,
    version_info::Channel channel,
    const std::string& product_category_for_subtypes,
    std::unique_ptr<ProfileIdentityProvider> identity_provider,
    std::unique_ptr<GCMClientFactory> gcm_client_factory,
    const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner,
    const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
    scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner)
    : profile_identity_provider_(std::move(identity_provider)),
      request_context_(request_context) {
  driver_ = CreateGCMDriverDesktop(
      std::move(gcm_client_factory), prefs,
      path.Append(gcm_driver::kGCMStoreDirname), request_context_, channel,
      product_category_for_subtypes, ui_task_runner, io_task_runner,
      blocking_task_runner);

  identity_observer_.reset(new IdentityObserver(
      profile_identity_provider_.get(), request_context_, driver_.get()));
}
#endif  // BUILDFLAG(USE_GCM_FROM_PLATFORM)

GCMProfileService::GCMProfileService() {}

GCMProfileService::~GCMProfileService() {}

void GCMProfileService::Shutdown() {
#if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
  identity_observer_.reset();
#endif  // !BUILDFLAG(USE_GCM_FROM_PLATFORM)
  if (driver_) {
    driver_->Shutdown();
    driver_.reset();
  }
}

void GCMProfileService::SetDriverForTesting(GCMDriver* driver) {
  driver_.reset(driver);
#if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
  if (identity_observer_) {
    identity_observer_.reset(new IdentityObserver(
        profile_identity_provider_.get(), request_context_, driver));
  }
#endif  // !BUILDFLAG(USE_GCM_FROM_PLATFORM)
}

}  // namespace gcm
