/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_
#define WEBRTC_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_

#include "webrtc/base/common.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/scoped_ptr.h"

namespace rtc {

template <typename Interface> class rcsf_ptr;

// A ReferenceCountedSingletonFactory is an object which owns another object,
// and doles out the owned object to consumers in a reference-counted manner.
// Thus, the factory owns at most one object of the desired kind, and
// hands consumers a special pointer to it, through which they can access it.
// When the consumers delete the pointer, the reference count goes down,
// and if the reference count hits zero, the factory can throw the object
// away.  If a consumer requests the pointer and the factory has none,
// it can create one on the fly and pass it back.
template <typename Interface>
class ReferenceCountedSingletonFactory {
  friend class rcsf_ptr<Interface>;
 public:
  ReferenceCountedSingletonFactory() : ref_count_(0) {}

  virtual ~ReferenceCountedSingletonFactory() {
    ASSERT(ref_count_ == 0);
  }

 protected:
  // Must be implemented in a sub-class. The sub-class may choose whether or not
  // to cache the instance across lifetimes by either reset()'ing or not
  // reset()'ing the scoped_ptr in CleanupInstance().
  virtual bool SetupInstance() = 0;
  virtual void CleanupInstance() = 0;

  scoped_ptr<Interface> instance_;

 private:
  Interface* GetInstance() {
    rtc::CritScope cs(&crit_);
    if (ref_count_ == 0) {
      if (!SetupInstance()) {
        LOG(LS_VERBOSE) << "Failed to setup instance";
        return NULL;
      }
      ASSERT(instance_.get() != NULL);
    }
    ++ref_count_;

    LOG(LS_VERBOSE) << "Number of references: " << ref_count_;
    return instance_.get();
  }

  void ReleaseInstance() {
    rtc::CritScope cs(&crit_);
    ASSERT(ref_count_ > 0);
    ASSERT(instance_.get() != NULL);
    --ref_count_;
    LOG(LS_VERBOSE) << "Number of references: " << ref_count_;
    if (ref_count_ == 0) {
      CleanupInstance();
    }
  }

  CriticalSection crit_;
  int ref_count_;

  RTC_DISALLOW_COPY_AND_ASSIGN(ReferenceCountedSingletonFactory);
};

template <typename Interface>
class rcsf_ptr {
 public:
  // Create a pointer that uses the factory to get the instance.
  // This is lazy - it won't generate the instance until it is requested.
  explicit rcsf_ptr(ReferenceCountedSingletonFactory<Interface>* factory)
      : instance_(NULL),
        factory_(factory) {
  }

  ~rcsf_ptr() {
    release();
  }

  Interface& operator*() {
    EnsureAcquired();
    return *instance_;
  }

  Interface* operator->() {
    EnsureAcquired();
    return instance_;
  }

  // Gets the pointer, creating the singleton if necessary. May return NULL if
  // creation failed.
  Interface* get() {
    Acquire();
    return instance_;
  }

  // Set instance to NULL and tell the factory we aren't using the instance
  // anymore.
  void release() {
    if (instance_) {
      instance_ = NULL;
      factory_->ReleaseInstance();
    }
  }

  // Lets us know whether instance is valid or not right now.
  // Even though attempts to use the instance will automatically create it, it
  // is advisable to check this because creation can fail.
  bool valid() const {
    return instance_ != NULL;
  }

  // Returns the factory that this pointer is using.
  ReferenceCountedSingletonFactory<Interface>* factory() const {
    return factory_;
  }

 private:
  void EnsureAcquired() {
    Acquire();
    ASSERT(instance_ != NULL);
  }

  void Acquire() {
    // Since we're getting a singleton back, acquire is a noop if instance is
    // already populated.
    if (!instance_) {
      instance_ = factory_->GetInstance();
    }
  }

  Interface* instance_;
  ReferenceCountedSingletonFactory<Interface>* factory_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(rcsf_ptr);
};

};  // namespace rtc

#endif  // WEBRTC_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_
