/*
 *  Copyright (c) 2012 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_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_

#include <assert.h>

#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#ifdef _WIN32
#include "webrtc/system_wrappers/include/fix_interlocked_exchange_pointer_win.h"
#endif

namespace webrtc {

enum CountOperation {
  kRelease,
  kAddRef,
  kAddRefNoCreate
};
enum CreateOperation {
  kInstanceExists,
  kCreate,
  kDestroy
};

template <class T>
// Construct On First Use idiom. Avoids
// "static initialization order fiasco".
static T* GetStaticInstance(CountOperation count_operation) {
  // TODO (hellner): use atomic wrapper instead.
  static volatile long instance_count = 0;
  static T* volatile instance = NULL;
  CreateOperation state = kInstanceExists;
#ifndef _WIN32
  // This memory is staticly allocated once. The application does not try to
  // free this memory. This approach is taken to avoid issues with
  // destruction order for statically allocated memory. The memory will be
  // reclaimed by the OS and memory leak tools will not recognize memory
  // reachable from statics leaked so no noise is added by doing this.
  static CriticalSectionWrapper* crit_sect(
    CriticalSectionWrapper::CreateCriticalSection());
  CriticalSectionScoped lock(crit_sect);

  if (count_operation ==
      kAddRefNoCreate && instance_count == 0) {
    return NULL;
  }
  if (count_operation ==
      kAddRef ||
      count_operation == kAddRefNoCreate) {
    instance_count++;
    if (instance_count == 1) {
      state = kCreate;
    }
  } else {
    instance_count--;
    if (instance_count == 0) {
      state = kDestroy;
    }
  }
  if (state == kCreate) {
    instance = T::CreateInstance();
  } else if (state == kDestroy) {
    T* old_instance = instance;
    instance = NULL;
    // The state will not change past this point. Release the critical
    // section while deleting the object in case it would be blocking on
    // access back to this object. (This is the case for the tracing class
    // since the thread owned by the tracing class also traces).
    // TODO(hellner): this is a bit out of place but here goes, de-couple
    // thread implementation with trace implementation.
    crit_sect->Leave();
    if (old_instance) {
      delete old_instance;
    }
    // Re-acquire the lock since the scoped critical section will release
    // it.
    crit_sect->Enter();
    return NULL;
  }
#else  // _WIN32
  if (count_operation ==
      kAddRefNoCreate && instance_count == 0) {
    return NULL;
  }
  if (count_operation == kAddRefNoCreate) {
    if (1 == InterlockedIncrement(&instance_count)) {
      // The instance has been destroyed by some other thread. Rollback.
      InterlockedDecrement(&instance_count);
      assert(false);
      return NULL;
    }
    // Sanity to catch corrupt state.
    if (instance == NULL) {
      assert(false);
      InterlockedDecrement(&instance_count);
      return NULL;
    }
  } else if (count_operation == kAddRef) {
    if (instance_count == 0) {
      state = kCreate;
    } else {
      if (1 == InterlockedIncrement(&instance_count)) {
        // InterlockedDecrement because reference count should not be
        // updated just yet (that's done when the instance is created).
        InterlockedDecrement(&instance_count);
        state = kCreate;
      }
    }
  } else {
    int new_value = InterlockedDecrement(&instance_count);
    if (new_value == 0) {
      state = kDestroy;
    }
  }

  if (state == kCreate) {
    // Create instance and let whichever thread finishes first assign its
    // local copy to the global instance. All other threads reclaim their
    // local copy.
    T* new_instance = T::CreateInstance();
    if (1 == InterlockedIncrement(&instance_count)) {
      InterlockedExchangePointer(reinterpret_cast<void * volatile*>(&instance),
                                 new_instance);
    } else {
      InterlockedDecrement(&instance_count);
      if (new_instance) {
        delete static_cast<T*>(new_instance);
      }
    }
  } else if (state == kDestroy) {
    T* old_value = static_cast<T*>(InterlockedExchangePointer(
        reinterpret_cast<void * volatile*>(&instance), NULL));
    if (old_value) {
      delete static_cast<T*>(old_value);
    }
    return NULL;
  }
#endif  // #ifndef _WIN32
  return instance;
}

}  // namspace webrtc

#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
