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

// A component is a large, long-lived set of functionality that may be enabled
// or disabled at runtime. Some examples include: the multizone features,
// MetricsRecorder, or OpencastController. Components may depend on each other
// (ie, a component may call the public methods of other components); the
// Component infrastructure ensures that when a component is disabled, nothing
// that depends on it will call any of its methods until it is enabled again.
//
// Components may be used without a dependency relationship via a weak
// reference. A weak reference does not allow direct access to the component;
// instead, it must be either used to create a strict dependency (see below), or
// be converted to a scoped reference via Try(). Scoped references must be
// checked for validity before use (they are convertible to bool); an invalid
// scoped reference must not be used. Scoped references should be short-lived;
// to encourage this, they are only move-constructible and cannot be copied or
// assigned.
//
// If component Y depends on Component X, then Y has a Dependency reference
// to X. This causes Y to be disabled as X is being disabled (before X's
// OnDisable() method is called). Similarly, this dependency will cause X to be
// enabled when Y is being enabled (X will be enabled before Y's OnEnable()
// method is called). A component may freely access any of its dependencies
// as long as it is enabled. When a component is disabled, it must ensure that
// none of its dependencies will be used again until it is enabled. It is
// recommended to set up dependencies in your component's constructor; it is an
// error to add a dependency to a component that is not disabled.
//
// When a component is disabled, it will first recursively disable any other
// components that depend on it. It will also disable the creation of
// new scoped references. It then waits for all scoped references to be
// destroyed before calling OnDisable() to actually disable the component.
//
// Components MUST be disabled before they are deleted. For ease of use, a
// Destroy() method is provided. When Destroy() is called, it prevents the
// component from being enabled ever again, and then disables it, deleting it
// once it is disabled.
//
// Example usage:
//
// class MetricsRecorder : public Component<MetricsRecorder> {
//  public:
//   virtual ~MetricsRecorder() {}
//   virtual void RecordEvent(const std::string& event) = 0;
// };
//
// class SetupManager : public Component<SetupManager> {
//  public:
//   virtual ~SetupManager() {}
//   virtual int GetMultizoneDelay() = 0;
// };
//
// class Multizone : public Component<Multizone> {
//  public:
//   virtual ~Multizone() {}
//   virtual void DoMultizoneStuff() = 0;
// };
//
// class MetricsRecorderImpl : public MetricsRecorder {
//  public:
//   void OnEnable() override {
//     // ... Enable metrics reporting ...
//     OnEnableComplete(true);
//   }
//
//   // Release all resources; public methods will not be called after this.
//   void OnDisable() override {
//     OnDisableComplete();
//   }
//
//   void RecordEvent(const std::string& event) override {
//     // ... Record an event ...
//   }
// };
//
// class SetupManagerImpl : public SetupManager {
//  public:
//   void OnEnable() override {
//     // ... Enable setup manager ...
//     // OnEnableComplete() may be called asynchronously.
//     base::ThreadTaskRunnerHandle::Get()->PostTask(
//         FROM_HERE, base::BindOnce(&SetupManagerImpl::CompleteEnable,
//                                   base::Unretained(this)));
//   }
//
//   void CompleteEnable() {
//     OnEnableComplete(true);
//   }
//
//   void OnDisable() override {
//     OnDisableComplete();
//   }
//
//   int GetMultizoneDelay() override { return 0; }
// };
//
// class MultizoneImpl : public Multizone {
//  public:
//   MultizoneImpl(const MetricsRecorder::WeakRef& metrics_recorder,
//                 const SetupManager::WeakRef& setup_manager)
//       : metrics_recorder_(metrics_recorder, this),
//         setup_manager_(setup_manager) {
//     // We can try to use weak deps even before this component is enabled.
//     // However, we MUST NOT attempt to use any strong dependencies.
//     if (auto setup = setup_manager_.Try()) {
//       int delay = setup->GetMultizoneDelay();
//       // ... Do something with delay ...
//     }
//   }
//
//   void OnEnable() override {
//     // ... Enable multizone ...
//     // Can use strong dependencies directly
//     metrics_recorder_->RecordEvent("enable multizone");
//     OnEnableComplete();
//   }
//
//   void OnDisable() override {
//     // Can still use strong dependencies here. However, this method MUST
//     // ensure that strong dependencies will NOT be used after it returns.
//     metrics_recorder_->RecordEvent("disable multizone");
//     OnDisableComplete();
//   }
//
//   void DoMultizoneStuff() {
//     metrics_recorder_->RecordEvent("multizone stuff");
//     // You have to Try() every time you use a weak dependency.
//     if (auto setup = setup_manager_.Try()) {
//       int delay = setup->GetMultizoneDelay();
//       // ... Do something with delay ...
//     }
//   }
//
//  private:
//   MetricsRecorder::Dependency metrics_recorder_;
//   SetupManager::WeakRef setup_manager_;
// };

#ifndef CHROMECAST_BASE_COMPONENT_COMPONENT_H_
#define CHROMECAST_BASE_COMPONENT_COMPONENT_H_

#include <vector>

#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/threading/thread_checker.h"
#include "chromecast/base/component/component_internal.h"

namespace base {
class SingleThreadTaskRunner;
}  // namespace base

namespace chromecast {

class ComponentBase {
 public:
  class Observer {
   public:
    // Called when a component finishes being enabled. If the component was
    // enabled successfully, |success| will be |true|. Note that access to
    // |component| is not guaranteed to be safe; since the observers are
    // notified asynchronously, |component| may have been already deleted.
    virtual void OnComponentEnabled(ComponentBase* component, bool success) {}
    // Called when a component has been disabled. Access to |component| is not
    // guaranteed to be safe.
    virtual void OnComponentDisabled(ComponentBase* component) {}

   protected:
    virtual ~Observer() {}
  };

  virtual ~ComponentBase();

  // Enables this component if possible. Attempts to enable all strong
  // dependencies first. It is OK to call Disable() while the component is in
  // the process of being enabled. All components MUST be created/enabled/
  // disabled/destroyed on the same thread.
  // Note that enabling a component may occur asynchronously; components must
  // always be accessed through a Dependency or WeakReference to ensure safety.
  // TODO(kmackay) Consider allowing components to be used on any thread.
  void Enable();

  // Disables this component; disabling may complete asynchronously. It is OK to
  // call Enable() again while the component is being disabled. Note that a
  // component MUST be disabled (or never enabled) before it is deleted.
  void Disable();

  // Deletes this component, disabling it first if necessary.
  void Destroy();

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

 protected:
  ComponentBase();

  // Enables the component implementation. This method must set things up so
  // that any public method calls are valid, and then call OnEnableComplete(),
  // passing in |true| if the enable was successful, |false| otherwise.
  // OnEnableComplete() may be called from any thread. OnEnable() will not be
  // called again until after the component has been disabled, and will not be
  // called during an ongoing OnDisable() call (so if OnDisable() is called,
  // then OnEnable() will not be called until OnDisableComplete() has been
  // called). This method is called only on the thread that the component was
  // created on.
  virtual void OnEnable() = 0;

  // Disables the component implementation. This is not called until there are
  // no more live dependencies, so there will be no more public method calls
  // to the component until after OnEnable() is called again. This method must
  // do whatever is necessary to ensure that no more calls to dependencies of
  // this component will be made, and then call the |disabled_cb|. The
  // |disabled_cb| may be called from any thread. This method is called only on
  // the thread that the component was created on.
  virtual void OnDisable() = 0;

  // Handles the success/failure of a call to OnEnable(). When OnEnable() is
  // called, it must eventually call OnEnableComplete() (after the component is
  // ready to be used by dependents), passing in |true| if the component was
  // enabled successfully. If |success| is false, then OnDisable() will be
  // called immediately to return the component to a consistent disabled state.
  // May be called on any thread.
  void OnEnableComplete(bool success);

  // Handles the completion of a call to OnDisable(). When OnDisable() is
  // called, it must eventually call OnDisableComplete() (after ensuring that
  // none of the component's strong dependencies will be used anymore). May be
  // called on any thread.
  void OnDisableComplete();

 private:
  friend class subtle::DependencyCount;
  friend class subtle::DependencyBase;
  friend class subtle::WeakReferenceBase;

  enum State {
    kStateDisabled,
    kStateDisabling,
    kStateEnabled,
    kStateEnabling,
    kStateDestroying
  };

  void DependencyReady();
  void TryOnEnable();
  void OnEnableCompleteInternal(bool success);
  void DependencyCountDisableComplete();
  void TryOnDisable();
  void OnDisableCompleteInternal();
  void AddDependency(subtle::DependencyBase* dependency);
  void StopUsingDependencies();
  // Returns |true| if |component| is a transitive dependency of this component.
  bool DependsOn(ComponentBase* component);

  const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  scoped_refptr<subtle::DependencyCount> counter_;
  std::vector<subtle::DependencyBase*> strong_dependencies_;
  State state_;
  // |true| when a call to OnEnable()/OnDisable() is in progress.
  bool async_call_in_progress_;
  int pending_dependency_count_;
  const scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;

  DISALLOW_COPY_AND_ASSIGN(ComponentBase);
};

template <typename C>
class StrongDependency : public subtle::DependencyBase {
 public:
  StrongDependency(const WeakReference<C>& dependency, ComponentBase* dependent)
      : subtle::DependencyBase(dependency, dependent) {}

  C* operator->() const {
    DCHECK(dependency_);
    return static_cast<C*>(dependency_);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(StrongDependency);
};

template <typename C>
class WeakReference : public subtle::WeakReferenceBase {
 public:
  explicit WeakReference(const C& dependency) : WeakReferenceBase(dependency) {}
  explicit WeakReference(const StrongDependency<C>& dependency)
      : subtle::WeakReferenceBase(dependency) {}

  // Explicitly allow copy.
  WeakReference(const WeakReference& other) = default;
  WeakReference(WeakReference&& other) = default;

  // Disallow assignment.
  void operator=(const WeakReference&) = delete;

  // Try to get a scoped reference. Expected usage:
  // if (auto ref = weak.Try()) {
  //    // ... use ref ...
  // }
  subtle::Ref_DO_NOT_DECLARE<C> Try() const {
    return subtle::Ref_DO_NOT_DECLARE<C>(counter_);
  }
};

template <typename C>
class Component : public ComponentBase {
 public:
  using WeakRef = WeakReference<C>;
  using Dependency = StrongDependency<C>;

  Component() = default;

  WeakRef GetRef() { return WeakRef(*static_cast<C*>(this)); }

 private:
  DISALLOW_COPY_AND_ASSIGN(Component);
};

}  // namespace chromecast

#endif  // CHROMECAST_BASE_COMPONENT_COMPONENT_H_
