// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_ARC_AUTH_ARC_AUTH_CONTEXT_H_
#define CHROME_BROWSER_ASH_ARC_AUTH_ARC_AUTH_CONTEXT_H_

#include <memory>
#include <string>

#include "base/functional/callback.h"
#include "base/memory/raw_ref.h"
#include "base/timer/timer.h"
#include "components/account_id/account_id.h"
#include "components/signin/public/identity_manager/identity_manager.h"

namespace arc {

class ArcAuthContext : public signin::IdentityManager::Observer {
 public:
  // Creates an |ArcAuthContext| for the given |account_id|. This |account_id|
  // must be the |account_id| used by the OAuth Token Service chain.
  // Note: |account_id| can be the Device Account or a Secondary Account stored
  // in Chrome OS Account Manager.
  // `identity_manager` must not be nullptr and must outlive this instance
  ArcAuthContext(signin::IdentityManager* identity_manager,
                 const CoreAccountId& account_id);

  ArcAuthContext(const ArcAuthContext&) = delete;
  ArcAuthContext& operator=(const ArcAuthContext&) = delete;

  ~ArcAuthContext() override;

  // Prepares the context. Calling while an inflight operation exists will
  // cancel the inflight operation.
  // On completion, |true| is passed to the callback. On error, |false|
  // is passed.
  using PrepareCallback = base::OnceCallback<void(bool success)>;
  void Prepare(PrepareCallback callback);

  // Creates and starts a request to fetch an access token. The caller owns the
  // returned request. |callback| will be called with results if the returned
  // request is not deleted.
  std::unique_ptr<signin::AccessTokenFetcher> CreateAccessTokenFetcher(
      const signin::OAuthConsumerId consumer_id,
      signin::AccessTokenFetcher::TokenCallback callback);

  void RemoveAccessTokenFromCache(const signin::OAuthConsumerId consumer_id,
                                  const std::string& access_token);

  // signin::IdentityManager::Observer:
  void OnRefreshTokenUpdatedForAccount(
      const CoreAccountInfo& account_info) override;
  void OnRefreshTokensLoaded() override;

 private:
  void OnRefreshTokenTimeout();

  const raw_ref<signin::IdentityManager> identity_manager_;
  const CoreAccountId account_id_;

  PrepareCallback callback_;
  bool context_prepared_ = false;

  base::OneShotTimer refresh_token_timeout_;
};

}  // namespace arc

#endif  // CHROME_BROWSER_ASH_ARC_AUTH_ARC_AUTH_CONTEXT_H_
