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

#include "peridot/lib/firebase_auth/testing/test_token_manager.h"

#include <fuchsia/auth/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/cpp/clone.h>
#include <lib/fidl/cpp/optional.h>
#include <lib/fxl/logging.h>

namespace firebase_auth {
TestTokenManager::TestTokenManager(async_dispatcher_t* dispatcher)
    : dispatcher_(dispatcher) {
  status_to_return_ = fuchsia::auth::Status::OK;
}

TestTokenManager::~TestTokenManager() {}

void TestTokenManager::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 /*callback*/) {
  FXL_NOTIMPLEMENTED();
}

void TestTokenManager::GetAccessToken(
    AppConfig app_config, fidl::StringPtr /*user_profile_id*/,
    fidl::VectorPtr<fidl::StringPtr> /*app_scopes*/,
    GetAccessTokenCallback callback /*callback*/) {
  FXL_NOTIMPLEMENTED();
}

void TestTokenManager::GetIdToken(AppConfig app_config,
                                  fidl::StringPtr /*user_profile_id*/,
                                  fidl::StringPtr /*audience*/,
                                  GetIdTokenCallback callback /*callback*/) {
  FXL_NOTIMPLEMENTED();
}

void TestTokenManager::GetFirebaseToken(AppConfig /*app_config*/,
                                        fidl::StringPtr /*user_profile_id*/,
                                        fidl::StringPtr /*audience*/,
                                        fidl::StringPtr /*firebase_api_key*/,
                                        GetFirebaseTokenCallback callback) {
  fuchsia::auth::FirebaseTokenPtr token_to_return_copy;
  fidl::Clone(token_to_return_, &token_to_return_copy);
  fuchsia::auth::Status status_to_return_copy;
  status_to_return_copy = status_to_return_;
  async::PostTask(dispatcher_,
                  [status_to_return = status_to_return_copy,
                   token_to_return = std::move(token_to_return_copy),
                   callback = std::move(callback)]() mutable {
                    callback(status_to_return, std::move(token_to_return));
                  });
}

void TestTokenManager::DeleteAllTokens(AppConfig /*app_config*/,
                                       fidl::StringPtr /*user_profile_id*/,
                                       DeleteAllTokensCallback callback) {
  FXL_NOTIMPLEMENTED();
}

void TestTokenManager::ListProfileIds(AppConfig app_config,
                                      ListProfileIdsCallback callback) {
  FXL_NOTIMPLEMENTED();
}

void TestTokenManager::Set(std::string id_token, std::string local_id,
                           std::string email) {
  token_to_return_ = fuchsia::auth::FirebaseToken::New();
  token_to_return_->id_token = id_token;
  token_to_return_->local_id = local_id;
  token_to_return_->email = email;
  status_to_return_ = fuchsia::auth::Status::OK;
}

void TestTokenManager::SetError(fuchsia::auth::Status status) {
  FXL_CHECK(status != fuchsia::auth::Status::OK);
  token_to_return_ = nullptr;
  status_to_return_ = status;
}
}  // namespace firebase_auth
