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

#include "content/browser/webauth/authenticator_environment.h"

#include <algorithm>
#include <utility>

#include "base/containers/contains.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "content/browser/webauth/virtual_authenticator.h"
#include "content/browser/webauth/virtual_discovery.h"
#include "content/browser/webauth/virtual_fido_discovery_factory.h"
#include "content/public/browser/scoped_authenticator_environment_for_testing.h"
#include "device/fido/fido_discovery_factory.h"

namespace content {

ScopedAuthenticatorEnvironmentForTesting::
    ScopedAuthenticatorEnvironmentForTesting(
        std::unique_ptr<device::FidoDiscoveryFactory> factory) {
  AuthenticatorEnvironment* impl = AuthenticatorEnvironment::GetInstance();
  CHECK(impl->MaybeGetDiscoveryFactoryTestOverride() == nullptr);
  impl->ReplaceDefaultDiscoveryFactoryForTesting(std::move(factory));
}

ScopedAuthenticatorEnvironmentForTesting::
    ~ScopedAuthenticatorEnvironmentForTesting() {
  AuthenticatorEnvironment* impl = AuthenticatorEnvironment::GetInstance();
  CHECK(impl->MaybeGetDiscoveryFactoryTestOverride() != nullptr);
  impl->ReplaceDefaultDiscoveryFactoryForTesting(nullptr);
}

// static
AuthenticatorEnvironment* AuthenticatorEnvironment::GetInstance() {
  static base::NoDestructor<AuthenticatorEnvironment> environment;
  return environment.get();
}

AuthenticatorEnvironment::AuthenticatorEnvironment() = default;

AuthenticatorEnvironment::~AuthenticatorEnvironment() = default;

void AuthenticatorEnvironment::Reset() {
  for (const auto& pair : virtual_authenticator_managers_) {
    pair.first->RemoveObserver(this);
  }
  virtual_authenticator_managers_.clear();

  replaced_discovery_factory_.reset();
}

void AuthenticatorEnvironment::EnableVirtualAuthenticatorFor(
    FrameTreeNode* node,
    bool enable_ui) {
  // Do not create a new virtual authenticator if there is one already defined
  // for the |node|.
  if (base::Contains(virtual_authenticator_managers_, node)) {
    return;
  }

  node->AddObserver(this);
  auto virtual_authenticator_manager =
      std::make_unique<VirtualAuthenticatorManagerImpl>();
  virtual_authenticator_manager->enable_ui(enable_ui);
  virtual_authenticator_managers_[node] =
      std::move(virtual_authenticator_manager);
}

void AuthenticatorEnvironment::DisableVirtualAuthenticatorFor(
    FrameTreeNode* node) {
  if (!base::Contains(virtual_authenticator_managers_, node)) {
    return;
  }

  node->RemoveObserver(this);
  virtual_authenticator_managers_.erase(node);
}

bool AuthenticatorEnvironment::IsVirtualAuthenticatorEnabledFor(
    FrameTreeNode* node) {
  return MaybeGetVirtualAuthenticatorManager(node) != nullptr;
}

VirtualAuthenticatorManagerImpl*
AuthenticatorEnvironment::MaybeGetVirtualAuthenticatorManager(
    FrameTreeNode* node) {
  for (; node; node = FrameTreeNode::From(node->parent())) {
    if (base::Contains(virtual_authenticator_managers_, node)) {
      return virtual_authenticator_managers_[node].get();
    }
  }
  return nullptr;
}

bool AuthenticatorEnvironment::HasVirtualUserVerifyingPlatformAuthenticator(
    FrameTreeNode* node) {
  VirtualAuthenticatorManagerImpl* authenticator_manager =
      MaybeGetVirtualAuthenticatorManager(node);
  if (!authenticator_manager) {
    return false;
  }
  std::vector<VirtualAuthenticator*> authenticators =
      authenticator_manager->GetAuthenticators();
  return std::ranges::any_of(authenticators, [](VirtualAuthenticator* a) {
    return a->is_user_verifying_platform_authenticator();
  });
}

device::FidoDiscoveryFactory*
AuthenticatorEnvironment::MaybeGetDiscoveryFactoryTestOverride() {
  return replaced_discovery_factory_.get();
}

void AuthenticatorEnvironment::ReplaceDefaultDiscoveryFactoryForTesting(
    std::unique_ptr<device::FidoDiscoveryFactory> factory) {
  replaced_discovery_factory_ = std::move(factory);
}

void AuthenticatorEnvironment::OnFrameTreeNodeDestroyed(FrameTreeNode* node) {
  DisableVirtualAuthenticatorFor(node);
}

}  // namespace content
