// 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 "components/gcm_driver/account_tracker.h"

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "components/signin/public/identity_manager/access_token_info.h"

namespace gcm {

AccountTracker::AccountTracker(signin::IdentityManager* identity_manager)
    : identity_manager_(identity_manager), shutdown_called_(false) {
  identity_manager_->AddObserver(this);
}

AccountTracker::~AccountTracker() {
  DCHECK(shutdown_called_);
}

void AccountTracker::Shutdown() {
  shutdown_called_ = true;
  identity_manager_->RemoveObserver(this);
}

void AccountTracker::AddObserver(Observer* observer) {
  observer_list_.AddObserver(observer);
}

void AccountTracker::RemoveObserver(Observer* observer) {
  observer_list_.RemoveObserver(observer);
}

std::vector<CoreAccountInfo> AccountTracker::GetAccounts() const {
  const CoreAccountId active_account_id =
      identity_manager_->GetPrimaryAccountId();
  std::vector<CoreAccountInfo> accounts;

  for (auto it = accounts_.begin(); it != accounts_.end(); ++it) {
    const AccountState& state = it->second;
    DCHECK(!state.account.account_id.empty());
    DCHECK(!state.account.gaia.empty());
    DCHECK(!state.account.email.empty());
    bool is_visible = state.is_signed_in;

    if (it->first == active_account_id) {
      if (is_visible)
        accounts.insert(accounts.begin(), state.account);
      else
        return std::vector<CoreAccountInfo>();
    } else if (is_visible) {
      accounts.push_back(state.account);
    }
  }
  return accounts;
}

void AccountTracker::OnRefreshTokenUpdatedForAccount(
    const CoreAccountInfo& account_info) {
  TRACE_EVENT1("identity", "AccountTracker::OnRefreshTokenUpdatedForAccount",
               "account_id", account_info.account_id.ToString());

  // Ignore refresh tokens if there is no active account ID at all.
  if (!identity_manager_->HasPrimaryAccount())
    return;

  DVLOG(1) << "AVAILABLE " << account_info.account_id;
  StartTrackingAccount(account_info);
  UpdateSignInState(account_info.account_id, /*is_signed_in=*/true);
}

void AccountTracker::OnRefreshTokenRemovedForAccount(
    const CoreAccountId& account_id) {
  TRACE_EVENT1("identity", "AccountTracker::OnRefreshTokenRemovedForAccount",
               "account_id", account_id.ToString());

  DVLOG(1) << "REVOKED " << account_id;
  UpdateSignInState(account_id, /*is_signed_in=*/false);
}

void AccountTracker::OnPrimaryAccountSet(
    const CoreAccountInfo& primary_account_info) {
  TRACE_EVENT0("identity", "AccountTracker::OnPrimaryAccountSet");

  std::vector<CoreAccountInfo> accounts =
      identity_manager_->GetAccountsWithRefreshTokens();

  DVLOG(1) << "LOGIN " << accounts.size() << " accounts available.";

  for (const CoreAccountInfo& account_info : accounts) {
    StartTrackingAccount(account_info);
    UpdateSignInState(account_info.account_id, /*is_signed_in=*/true);
  }
}

void AccountTracker::OnPrimaryAccountCleared(
    const CoreAccountInfo& previous_primary_account_info) {
  TRACE_EVENT0("identity", "AccountTracker::OnPrimaryAccountCleared");
  DVLOG(1) << "LOGOUT";
  StopTrackingAllAccounts();
}

void AccountTracker::UpdateSignInState(const CoreAccountId& account_id,
                                       bool is_signed_in) {
  if (!is_signed_in && !base::Contains(accounts_, account_id))
    return;

  DCHECK(base::Contains(accounts_, account_id));
  AccountState& account = accounts_[account_id];
  if (account.is_signed_in == is_signed_in)
    return;

  account.is_signed_in = is_signed_in;
  for (auto& observer : observer_list_)
    observer.OnAccountSignInChanged(account.account, account.is_signed_in);
}

void AccountTracker::StartTrackingAccount(const CoreAccountInfo& account) {
  if (base::Contains(accounts_, account.account_id))
    return;

  DVLOG(1) << "StartTracking " << account.account_id;
  AccountState account_state;
  account_state.account = account;
  account_state.is_signed_in = false;
  accounts_.insert(std::make_pair(account.account_id, account_state));
}

void AccountTracker::StopTrackingAccount(const CoreAccountId account_id) {
  DVLOG(1) << "StopTracking " << account_id;
  if (base::Contains(accounts_, account_id)) {
    UpdateSignInState(account_id, /*is_signed_in=*/false);
    accounts_.erase(account_id);
  }
}

void AccountTracker::StopTrackingAllAccounts() {
  while (!accounts_.empty())
    StopTrackingAccount(accounts_.begin()->first);
}

}  // namespace gcm
