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

#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_AUTOFILL_DRIVER_FACTORY_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_AUTOFILL_DRIVER_FACTORY_H_

#include <vector>

#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "components/autofill/core/browser/foundations/autofill_driver.h"

namespace autofill {

// The common interface for platform-dependent AutofillDriver factories:
// - ContentAutofillDriverFactory
// - AutofillDriverIOSFactory
//
// AutofillDriverFactory must create at most one AutofillDriver per frame-like
// object (e.g., content::RenderFrameHost) and manage their lifecycle
// corresponding to the frame-like object's lifecycle.
//
// AutofillDriverFactory must be owned by AutofillClient, so there is at most
// one instance per tab-like object (e.g., content::WebContents).
class AutofillDriverFactory {
 public:
  using LifecycleState = AutofillDriver::LifecycleState;

  // Observer of AutofillDriverFactory events.
  class Observer : public base::CheckedObserver {
   public:
    // Called during destruction of the AutofillDriverFactory. It can,
    // e.g., be used to reset `ScopedObservation`s.
    virtual void OnAutofillDriverFactoryDestroyed(
        AutofillDriverFactory& factory) {}

    // Called right after the driver has been created.
    // At the time of this event, the `driver` object is already fully alive and
    // `factory.DriverForFrame(driver.render_frame_host()) == &driver` (or
    // similarly for iOS) holds. The driver's manager is still in its
    // `kInactive` state at the time.
    virtual void OnAutofillDriverCreated(AutofillDriverFactory& factory,
                                         AutofillDriver& driver) {}

    // Called right after the driver's state has changed.
    // See AutofillDriver::LifecycleState for details.
    // At the time of this event, the `driver` object is fully alive and
    // `factory.DriverForFrame(driver.render_frame_host()) == &driver` (or
    // similarly for iOS) holds.
    virtual void OnAutofillDriverStateChanged(AutofillDriverFactory& factory,
                                              AutofillDriver& driver,
                                              LifecycleState old_state,
                                              LifecycleState new_state) {}
  };

  AutofillDriverFactory();
  AutofillDriverFactory(AutofillDriverFactory&) = delete;
  AutofillDriverFactory& operator=(const AutofillDriverFactory&) = delete;
  virtual ~AutofillDriverFactory();

  void AddObserver(Observer* observer) { observers_.AddObserver(observer); }

  void RemoveObserver(Observer* observer) {
    observers_.RemoveObserver(observer);
  }

  // Returns raw pointers to all drivers that the factory currently owns.
  virtual std::vector<AutofillDriver*> GetExistingDrivers() = 0;

 protected:
  friend class AutofillDriverFactoryTestApi;

  void SetLifecycleStateAndNotifyObservers(AutofillDriver& driver,
                                           LifecycleState new_state);

  // TODO(crbug.com/484371187): Investigate if reentrancy can be removed.
  const base::ObserverList<
      Observer,
      /*check_empty=*/false,
      base::ObserverListReentrancyPolicy::kAllowReentrancyUntriaged>&
  observers() {
    return observers_;
  }

 private:
  // TODO(crbug.com/484371187): Investigate if reentrancy can be removed.
  base::ObserverList<
      Observer,
      /*check_empty=*/false,
      base::ObserverListReentrancyPolicy::kAllowReentrancyUntriaged>
      observers_;
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_AUTOFILL_DRIVER_FACTORY_H_
