// 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_CFX_OBSERVABLE_H_
#define CORE_FXCRT_CFX_OBSERVABLE_H_

#include <set>

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

template <class T>
class CFX_Observable {
 public:
  class ObservedPtr {
   public:
    ObservedPtr() : m_pObservedPtr(nullptr) {}
    explicit ObservedPtr(T* pObservedPtr) : m_pObservedPtr(pObservedPtr) {
      if (m_pObservedPtr)
        m_pObservedPtr->AddObservedPtr(this);
    }
    ObservedPtr(const ObservedPtr& that) = delete;
    ~ObservedPtr() {
      if (m_pObservedPtr)
        m_pObservedPtr->RemoveObservedPtr(this);
    }
    void Reset(T* pObservedPtr = nullptr) {
      if (m_pObservedPtr)
        m_pObservedPtr->RemoveObservedPtr(this);
      m_pObservedPtr = pObservedPtr;
      if (m_pObservedPtr)
        m_pObservedPtr->AddObservedPtr(this);
    }
    void OnDestroy() {
      ASSERT(m_pObservedPtr);
      m_pObservedPtr = nullptr;
    }
    ObservedPtr& operator=(const ObservedPtr& that) = delete;
    bool operator==(const ObservedPtr& that) const {
      return m_pObservedPtr == that.m_pObservedPtr;
    }
    bool operator!=(const ObservedPtr& that) const { return !(*this == that); }
    explicit operator bool() const { return !!m_pObservedPtr; }
    T* Get() const { return m_pObservedPtr; }
    T& operator*() const { return *m_pObservedPtr; }
    T* operator->() const { return m_pObservedPtr; }

   private:
    T* m_pObservedPtr;
  };

  CFX_Observable() {}
  CFX_Observable(const CFX_Observable& that) = delete;
  ~CFX_Observable() { NotifyObservedPtrs(); }
  void AddObservedPtr(ObservedPtr* pObservedPtr) {
    ASSERT(!pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr));
    m_ObservedPtrs.insert(pObservedPtr);
  }
  void RemoveObservedPtr(ObservedPtr* pObservedPtr) {
    ASSERT(pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr));
    m_ObservedPtrs.erase(pObservedPtr);
  }
  void NotifyObservedPtrs() {
    for (auto* pObservedPtr : m_ObservedPtrs)
      pObservedPtr->OnDestroy();
    m_ObservedPtrs.clear();
  }
  CFX_Observable& operator=(const CFX_Observable& that) = delete;

 protected:
  size_t ActiveObservedPtrsForTesting() const { return m_ObservedPtrs.size(); }

 private:
  std::set<ObservedPtr*> m_ObservedPtrs;
};

#endif  // CORE_FXCRT_CFX_OBSERVABLE_H_
