// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_FAKE_TOKEN_MANAGER_H_
#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_FAKE_TOKEN_MANAGER_H_

#include <functional>

#include <fuchsia/auth/cpp/fidl.h>
#include <lib/fxl/macros.h>

#include "peridot/lib/rng/random.h"

namespace firebase_auth {

using fuchsia::auth::AppConfig;
using fuchsia::auth::AuthenticationUIContext;

// FakeTokenManager is a dummy implementation of a TokenManager intended to be
// used to connect to unauthenticated firebase instances.
//
// The local ID Firebase token are set to a random UUID fixed at the
// construction time.
//
// Other token values are set to dummy const values.
class FakeTokenManager : public fuchsia::auth::TokenManager {
 public:
  FakeTokenManager(rng::Random* random);
  ~FakeTokenManager() override {}

 private:
  // fuchsia::auth::TokenManager:
  void Authorize(AppConfig app_config,
                 fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
                 fidl::VectorPtr<fidl::StringPtr> app_scopes,
                 fidl::StringPtr user_profile_id, fidl::StringPtr auth_code,
                 AuthorizeCallback callback) override;

  void GetAccessToken(AppConfig app_config, fidl::StringPtr user_profile_id,
                      fidl::VectorPtr<fidl::StringPtr> app_scopes,
                      GetAccessTokenCallback callback) override;

  void GetIdToken(AppConfig app_config, fidl::StringPtr user_profile_id,
                  fidl::StringPtr audience,
                  GetIdTokenCallback callback) override;

  void GetFirebaseToken(AppConfig app_config, fidl::StringPtr user_profile_id,
                        fidl::StringPtr audience,
                        fidl::StringPtr firebase_api_key,
                        GetFirebaseTokenCallback callback) override;

  void DeleteAllTokens(AppConfig app_config, fidl::StringPtr user_profile_id,
                       DeleteAllTokensCallback callback) override;

  void ListProfileIds(AppConfig app_config,
                      ListProfileIdsCallback callback) override;

  // Sets the token to return to null, and status to |status|.
  std::string firebase_id_token_;
  std::string firebase_local_id_;
  std::string email_;
  FXL_DISALLOW_COPY_AND_ASSIGN(FakeTokenManager);
};

}  // namespace firebase_auth

#endif  // PERIDOT_LIB_FIREBASE_AUTH_TESTING_FAKE_TOKEN_MANAGER_H_
