// Copyright 2016 PDFium 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 CORE_FXCRT_OBSERVABLE_H_
#define CORE_FXCRT_OBSERVABLE_H_

#include <set>

#include "core/fxcrt/fx_system.h"
#include "third_party/base/stl_util.h"

namespace fxcrt {

template <class T>
class Observable {
 public:
  // General-purpose interface for more complicated cleanup.
  class Observer {
   public:
    virtual ~Observer() = default;
    virtual void OnObservableDestroyed() = 0;
  };

  // Simple case of a self-nulling pointer.
  class ObservedPtr final : public Observer {
   public:
    ObservedPtr() : m_pObservable(nullptr) {}
    explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) {
      if (m_pObservable)
        m_pObservable->AddObserver(this);
    }
    ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {}
    ~ObservedPtr() {
      if (m_pObservable)
        m_pObservable->RemoveObserver(this);
    }
    void Reset(T* pObservable = nullptr) {
      if (m_pObservable)
        m_pObservable->RemoveObserver(this);
      m_pObservable = pObservable;
      if (m_pObservable)
        m_pObservable->AddObserver(this);
    }
    void OnObservableDestroyed() override {
      ASSERT(m_pObservable);
      m_pObservable = nullptr;
    }
    ObservedPtr& operator=(const ObservedPtr& that) {
      Reset(that.Get());
      return *this;
    }
    bool operator==(const ObservedPtr& that) const {
      return m_pObservable == that.m_pObservable;
    }
    bool operator!=(const ObservedPtr& that) const { return !(*this == that); }
    explicit operator bool() const { return !!m_pObservable; }
    T* Get() const { return m_pObservable; }
    T& operator*() const { return *m_pObservable; }
    T* operator->() const { return m_pObservable; }

   private:
    T* m_pObservable;
  };

  Observable() = default;
  Observable(const Observable& that) = delete;
  ~Observable() { NotifyObservers(); }
  void AddObserver(Observer* pObserver) {
    ASSERT(!pdfium::ContainsKey(m_Observers, pObserver));
    m_Observers.insert(pObserver);
  }
  void RemoveObserver(Observer* pObserver) {
    ASSERT(pdfium::ContainsKey(m_Observers, pObserver));
    m_Observers.erase(pObserver);
  }
  void NotifyObservers() {
    for (auto* pObserver : m_Observers)
      pObserver->OnObservableDestroyed();
    m_Observers.clear();
  }
  Observable& operator=(const Observable& that) = delete;

 protected:
  size_t ActiveObserversForTesting() const { return m_Observers.size(); }

 private:
  std::set<Observer*> m_Observers;
};

}  // namespace fxcrt

using fxcrt::Observable;

#endif  // CORE_FXCRT_OBSERVABLE_H_
