// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef COBALT_BASE_C_VAL_H_
#define COBALT_BASE_C_VAL_H_

#include <stdint.h>

#include <iomanip>
#include <limits>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>

#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/optional.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "cobalt/base/ref_counted_lock.h"
#include "cobalt/base/type_id.h"

// The CVal system allows you to mark certain variables to be part of the
// CVal system and therefore analyzable and trackable by other systems.  All
// modifications to marked variables will trigger an event within a CValManager
// class, which will in turn trigger an event in all attached hooks (e.g. memory
// logging systems, tracing systems, etc...).

// Each marked variable is known as a CVal, and every CVal has an associated
// name so that it can be looked up at run time.  Thus, you can only ever
// have one CVal of the same name existing at a time.
//
// CVal's take a Visibility template parameter.  There are two valid options for
// it, CValDebug and CValPublic.  CValDebug is the default value.  They are
// identical when ENABLE_DEBUG_C_VAL is defined; however, when
// ENABLE_DEBUG_C_VAL is not defined, CVals with Visibility set to CValPublic
// remain trackable through the CVal system, while CVals with Visibility set to
// CValDebug stop being trackable and behave as similarly as possible to its
// underlying type.

// You can mark a variable:
//
//   int memory_counter;
//
// as a CVal by wrapping the type with the CVal template type:
//
//   CVal<int> memory_counter("Memory Counter", 0, "My memory counter");
//   CVal<int, CValDebug> memory_counter("Memory Counter", 0,
//                                       "My memory counter");
//   CVal<int, CValPublic> memory_counter("Memory Counter", 0,
//                                        "My memory counter");
//
// The first constructor parameter is the name of the CVal, the second is the
// initial value for the variable, and the third is the description.
//
// For the system to function, the singleton CValManager class must be
// instantiated.  If a CVal is created before a CValManager is instantiated, it
// will attach itself to the CValManager the next time it is modified.  Thus,
// global CVal variables can be supported, but they will not be tracked until
// they are modified for the first time after the CValManager is created.  At
// this point, while CVals will be tracked, you will only be notified of changes
// to CVals.
//
// To hook in to the CValManager in order to receive CVal changed notifications,
// you should create a class that subclasses CValManager::OnChangedHook and
// implements the OnValueChanged virtual method.  When this class is
// instantiated, it will automatically hook in to the singleton CValManager
// object, which must exist at that point.
//
// NOTE: When the debug console is disabled, change events are never tracked.

namespace base {

namespace CValDetail {

class CValBase;

template <typename T>
class CValImpl;

}  // namespace CValDetail

// CVals are commonly used for values that are in units of bytes.  By making
// a CVal of type SizeInBytes, this can be made explicit, and allows the CVal
// system to use KB/MB suffixes instead of K/M.
namespace cval {
class SizeInBytes {
 public:
  SizeInBytes(uint64 size_in_bytes)  // NOLINT(runtime/explicit)
      : size_in_bytes_(size_in_bytes) {}
  SizeInBytes& operator=(uint64 rhs) {
    size_in_bytes_ = rhs;
    return *this;
  }
  SizeInBytes& operator+=(const SizeInBytes& rhs) {
    size_in_bytes_ += rhs.size_in_bytes_;
    return *this;
  }
  SizeInBytes& operator-=(const SizeInBytes& rhs) {
    size_in_bytes_ -= rhs.size_in_bytes_;
    return *this;
  }
  operator uint64() const { return value(); }

  uint64 value() const { return size_in_bytes_; }

 private:
  uint64 size_in_bytes_;
};
inline std::ostream& operator<<(std::ostream& out, const SizeInBytes& size) {
  return out << static_cast<uint64>(size);
}
}  // namespace cval

namespace CValDetail {

// Provide methods to convert from an arbitrary type to a string, useful for
// systems that want to read the value of a CVal without caring about its type.
template <typename T>
std::string ValToString(const T& value) {
  std::ostringstream oss;
  oss << value;
  return oss.str();
}

template <>
inline std::string ValToString<bool>(const bool& value) {
  return value ? "true" : "false";
}

template <>
inline std::string ValToString<std::string>(const std::string& value) {
  return value;
}

template <>
inline std::string ValToString<base::TimeDelta>(const base::TimeDelta& value) {
  return ValToString(value.InMicroseconds());
}

// Helper function to implement the numerical branch of ValToPrettyString
template <typename T>
struct ThresholdListElement {
  T threshold;
  T divide_by;
  const char* postfix;
};
template <>
struct ThresholdListElement<cval::SizeInBytes> {
  uint64 threshold;
  uint64 divide_by;
  const char* postfix;
};
template <typename T>
struct ThresholdList {
  ThresholdList(ThresholdListElement<T>* array, size_t size)
      : array(array), size(size) {}
  ThresholdListElement<T>* array;
  size_t size;
};

template <typename T>
ThresholdList<T> GetThresholdList() {
  static ThresholdListElement<T> thresholds[] = {
      {static_cast<T>(10 * 1000 * 1000), static_cast<T>(1000 * 1000), "M"},
      {static_cast<T>(10 * 1000), static_cast<T>(1000), "K"},
  };
  return ThresholdList<T>(thresholds, arraysize(thresholds));
}

template <>
inline ThresholdList<cval::SizeInBytes> GetThresholdList<cval::SizeInBytes>() {
  static ThresholdListElement<cval::SizeInBytes> thresholds[] = {
      {10LL * 1024LL * 1024LL * 1024LL, 1024LL * 1024LL * 1024LL, "GB"},
      {10LL * 1024LL * 1024LL, 1024LL * 1024LL, "MB"},
      {10LL * 1024LL, 1024LL, "KB"},
      {0LL, 1L, "B"},
  };
  return ThresholdList<cval::SizeInBytes>(thresholds, arraysize(thresholds));
}

template <typename T>
std::string NumericalValToPrettyString(const T& value) {
  ThresholdList<T> threshold_list = GetThresholdList<T>();
  ThresholdListElement<T>* thresholds = threshold_list.array;

  T divided_value = value;
  const char* postfix = "";

  for (size_t i = 0; i < threshold_list.size; ++i) {
    if (value >= thresholds[i].threshold) {
      divided_value = value / thresholds[i].divide_by;
      postfix = thresholds[i].postfix;
      break;
    }
  }

  std::ostringstream oss;
  oss << divided_value << postfix;
  return oss.str();
}

template <>
inline std::string NumericalValToPrettyString<base::TimeDelta>(
    const base::TimeDelta& value) {
  const int64 kMicrosecond = 1LL;
  const int64 kMillisecond = 1000LL * kMicrosecond;
  const int64 kSecond = 1000LL * kMillisecond;
  const int64 kMinute = 60LL * kSecond;
  const int64 kHour = 60LL * kMinute;

  int64 value_in_us = value.InMicroseconds();
  bool negative = value_in_us < 0;
  value_in_us *= negative ? -1 : 1;

  std::ostringstream oss;
  if (negative) {
    oss << "-";
  }

  oss << std::fixed << std::setprecision(1) << std::setfill('0');
  if (value_in_us > kHour) {
    oss << value_in_us / kHour << ":" << std::setw(2)
        << (value_in_us % kHour) / kMinute << ":" << std::setw(2)
        << (value_in_us % kMinute) / kSecond << "h";
  } else if (value_in_us > kMinute) {
    oss << value_in_us / kMinute << ":" << std::setw(2)
        << (value_in_us % kMinute) / kSecond << "m";
  } else if (value_in_us > kSecond) {
    oss << std::setw(1) << static_cast<double>(value_in_us) / kSecond << "s";
  } else if (value_in_us > kMillisecond) {
    oss << std::setw(1) << static_cast<double>(value_in_us) / kMillisecond
        << "ms";
  } else {
    oss << value_in_us << "us";
  }

  return oss.str();
}

// Helper function for the subsequent ValToPrettyString function.
template <typename T, bool IsNumerical>
class ValToPrettyStringHelper {};
template <typename T>
class ValToPrettyStringHelper<T, true> {
 public:
  static std::string Call(const T& value) {
    return NumericalValToPrettyString(value);
  }
};
template <typename T>
class ValToPrettyStringHelper<T, false> {
 public:
  static std::string Call(const T& value) { return ValToString(value); }
};

template <typename T>
struct IsNumerical {
  static const bool value =
      (std::is_arithmetic<T>::value && !std::is_same<T, bool>::value) ||
      std::is_same<T, base::TimeDelta>::value ||
      std::is_same<T, cval::SizeInBytes>::value;
};

// As opposed to ValToString, here we take the opportunity to clean up the
// number a bit to make it easier for humans to digest.  For example, if a
// number is much larger than one million, we can divide it by one million
// and postfix it with an 'M'.
template <typename T>
std::string ValToPrettyString(const T& value) {
  return ValToPrettyStringHelper<T, IsNumerical<T>::value>::Call(value);
}

// Provides methods for converting the type to and from a double.
template <typename T>
double ToDouble(T value) {
  return static_cast<double>(value);
}
template <>
inline double ToDouble<base::TimeDelta>(base::TimeDelta value) {
  return static_cast<double>(value.InMicroseconds());
}

template <typename T>
T FromDouble(double value) {
  return static_cast<T>(value);
}
template <>
inline base::TimeDelta FromDouble<base::TimeDelta>(double value) {
  return base::TimeDelta::FromMicroseconds(static_cast<int64>(value));
}

// Provides methods for retrieving the max and min value for the type.
template <typename T>
T Max() {
  return std::numeric_limits<T>::max();
}
template <>
inline base::TimeDelta Max<base::TimeDelta>() {
  return base::TimeDelta::Max();
}

template <typename T>
T Min() {
  return std::numeric_limits<T>::min();
}
template <>
inline base::TimeDelta Min<base::TimeDelta>() {
  return -base::TimeDelta::Max();
}

}  // namespace CValDetail

#if defined(ENABLE_DEBUG_C_VAL)
// This class is passed back to the CVal modified event handlers so that they
// can examine the new CVal value.  This class knows its type, which can be
// checked through GetType, and then the actual value can be retrieved by
// calling CValGenericValue::AsNativeType<TYPE>() with the correct type.  If you
// don't care about the type, you can call CValGenericValue::AsString() and
// retrieve the string version of the value.
class CValGenericValue {
 public:
  TypeId GetTypeId() const { return type_id_; }

  // Return the value casted to the specified type.  The requested type must
  // match the contained value's actual native type.
  template <typename T>
  const T& AsNativeType() const {
    DCHECK(IsNativeType<T>());
    return *static_cast<T*>(generic_value_);
  }

  // Returns true if the type of this value is exactly T.
  template <typename T>
  bool IsNativeType() const {
    return type_id_ == base::GetTypeId<T>();
  }

  virtual std::string AsString() const = 0;
  virtual std::string AsPrettyString() const = 0;

 protected:
  CValGenericValue(TypeId type_id, void* value_mem)
      : type_id_(type_id), generic_value_(value_mem) {}
  virtual ~CValGenericValue() {}

 private:
  TypeId type_id_;
  void* generic_value_;
};

namespace CValDetail {

// Internally used to store the actual typed value that a CValGenericValue may
// contain.  This value actually stores the data as a copy and then passes a
// pointer (as a void*) to its parent class CValGenericValue so that the value
// can be accessed from the parent class.  This class is intended to snapshot a
// CVal value before passing it along to event handlers ensuring that they all
// receive the same value.
template <typename T>
class CValSpecificValue : public CValGenericValue {
 public:
  explicit CValSpecificValue(const T& value)
      : CValGenericValue(base::GetTypeId<T>(), &value_), value_(value) {}
  CValSpecificValue(const CValSpecificValue<T>& other)
      : CValGenericValue(base::GetTypeId<T>(), &value_), value_(other.value_) {}
  virtual ~CValSpecificValue() {}

  std::string AsString() const { return ValToString(value_); }

  std::string AsPrettyString() const { return ValToPrettyString(value_); }

 private:
  T value_;
};

}  // namespace CValDetail
#endif  // ENABLE_DEBUG_C_VAL

// Manager class required for the CVal tracking system to function.
// This class is designed to be a singleton, instanced only through the methods
// of the base::Singleton class. For example,
// CValManager::GetInstance()->GetValueAsPrettyString(...)
class CValManager {
 public:
  // Method to get the singleton instance of this class.
  static CValManager* GetInstance();

#if defined(ENABLE_DEBUG_C_VAL)
  // In order for a system to receive notifications when a tracked CVal changes,
  // it should create a subclass of OnChangedHook with OnValueChanged. When
  // instantiated, OnChangedHook will be called whenever a CVal changes.
  class OnChangedHook {
   public:
    OnChangedHook();
    virtual ~OnChangedHook();

    virtual void OnValueChanged(const std::string& name,
                                const CValGenericValue& value) = 0;
  };
#endif  // ENABLE_DEBUG_C_VAL

  friend struct base::StaticMemorySingletonTraits<CValManager>;

  // Returns a set of the sorted names of all CVals currently registered.
  std::set<std::string> GetOrderedCValNames();

  // Returns the value of the given CVal as a string.  The return value is a
  // pair, the first element is true if the CVal exists, in which case the
  // second element is the value (as a string).  If the CVal does not exist,
  // the value of the second element is undefined.
  Optional<std::string> GetValueAsString(const std::string& name);

  // Similar to the above, but formatting may be done on numerical values.
  // For example, large numbers may have metric postfixes appended to them.
  // i.e. 104857600 = 100M
  Optional<std::string> GetValueAsPrettyString(const std::string& name);

 private:
  // Class can only be instanced via the singleton
  CValManager();
  ~CValManager();

  // Called in CVal constructors to register/deregister themselves with the
  // system.  Registering a CVal will also provide that CVal with a value lock
  // to lock when it modifies its value.
  void RegisterCVal(const CValDetail::CValBase* cval,
                    scoped_refptr<base::RefCountedThreadSafeLock>* value_lock);
  void UnregisterCVal(const CValDetail::CValBase* cval);

#if defined(ENABLE_DEBUG_C_VAL)
  // Called whenever a CVal is modified, and does the work of notifying all
  // hooks.
  void PushValueChangedEvent(const CValDetail::CValBase* cval,
                             const CValGenericValue& value);
#endif  // ENABLE_DEBUG_C_VAL

  // Helper function to remove code duplication between GetValueAsString
  // and GetValueAsPrettyString.
  Optional<std::string> GetCValStringValue(const std::string& name,
                                           bool pretty);

#if defined(ENABLE_DEBUG_C_VAL)
  // Lock that protects against changes to hooks.
  base::Lock hooks_lock_;
#endif  // ENABLE_DEBUG_C_VAL

  // Lock that protects against CVals being registered/deregistered.
  base::Lock cvals_lock_;

  // Lock that synchronizes |value_| reads/writes. It exists as a refptr to
  // ensure that CVals that survive longer than the CValManager can continue
  // to use it after the CValManager has been destroyed.
  scoped_refptr<base::RefCountedThreadSafeLock> value_lock_refptr_;

  // The actual value registry, mapping CVal name to actual CVal object.
  typedef base::hash_map<std::string, const CValDetail::CValBase*> NameVarMap;
  NameVarMap* registered_vars_;

#if defined(ENABLE_DEBUG_C_VAL)
  // The set of hooks that we should notify whenever a CVal is modified.
  typedef base::hash_set<OnChangedHook*> OnChangeHookSet;
  OnChangeHookSet* on_changed_hook_set_;
#endif  // ENABLE_DEBUG_C_VAL

  template <typename T>
  friend class CValDetail::CValImpl;

  DISALLOW_COPY_AND_ASSIGN(CValManager);
};

namespace CValDetail {

class CValBase {
 public:
  CValBase(const std::string& name, TypeId type_id,
           const std::string& description)
      : name_(name), description_(description), type_id_(type_id) {}

  const std::string& GetName() const { return name_; }
  const std::string& GetDescription() const { return description_; }
  TypeId GetTypeId() const { return type_id_; }

  virtual std::string GetValueAsString() const = 0;
  virtual std::string GetValueAsPrettyString() const = 0;

 private:
  virtual void OnManagerDestroyed() const {}

  std::string name_;
  std::string description_;
  TypeId type_id_;

  friend CValManager;
};

// This is a wrapper class that marks that we wish to track a value through
// the CVal system.
template <typename T>
class CValImpl : public CValBase {
 public:
  CValImpl(const std::string& name, const T& initial_value,
           const std::string& description)
      : CValBase(name, base::GetTypeId<T>(), description),
        value_(initial_value) {
    CommonConstructor();
  }
  CValImpl(const std::string& name, const std::string& description)
      : CValBase(name, base::GetTypeId<T>(), description) {
    CommonConstructor();
  }
  virtual ~CValImpl() {
    if (registered_) {
      CValManager::GetInstance()->UnregisterCVal(this);
    }
  }

  operator T() const { return value(); }

  const CValImpl<T>& operator=(const T& rhs) {
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    bool value_changed = value_ != rhs;
    if (value_changed) {
      value_ = rhs;
#if defined(ENABLE_DEBUG_C_VAL)
      OnValueChanged();
#endif  // ENABLE_DEBUG_C_VAL
    }
    return *this;
  }

  const CValImpl<T>& operator+=(const T& rhs) {
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    value_ += rhs;
#if defined(ENABLE_DEBUG_C_VAL)
    OnValueChanged();
#endif  // ENABLE_DEBUG_C_VAL
    return *this;
  }

  const CValImpl<T>& operator-=(const T& rhs) {
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    value_ -= rhs;
#if defined(ENABLE_DEBUG_C_VAL)
    OnValueChanged();
#endif  // ENABLE_DEBUG_C_VAL
    return *this;
  }

  const CValImpl<T>& operator++() {
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    ++value_;
#if defined(ENABLE_DEBUG_C_VAL)
    OnValueChanged();
#endif  // ENABLE_DEBUG_C_VAL
    return *this;
  }

  const CValImpl<T>& operator--() {
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    --value_;
#if defined(ENABLE_DEBUG_C_VAL)
    OnValueChanged();
#endif  // ENABLE_DEBUG_C_VAL
    return *this;
  }

  bool operator<(const T& rhs) const { return value() < rhs; }
  bool operator>(const T& rhs) const { return value() > rhs; }
  bool operator==(const T& rhs) const { return value() == rhs; }

  std::string GetValueAsString() const {
    // Can be called to get the value of a CVal without knowing the type first.
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    return ValToString<T>(value_);
  }

  std::string GetValueAsPrettyString() const {
    // Similar to GetValueAsString(), but it will also format the string to
    // do things like make very large numbers more readable.
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    return ValToPrettyString<T>(value_);
  }

  T value() const {
    base::AutoLock auto_lock(value_lock_refptr_->GetLock());
    return value_;
  }

 private:
  void CommonConstructor() {
    registered_ = false;
    RegisterWithManager();
  }

  void RegisterWithManager() {
    if (!registered_) {
      CValManager* manager = CValManager::GetInstance();
      manager->RegisterCVal(this, &value_lock_refptr_);
      registered_ = true;
    }
  }

  void OnManagerDestroyed() const {
    // The value lock is locked by the manager prior to it calling
    // OnManagerDestroyed  on its surviving CVals.
    registered_ = false;
  }

#if defined(ENABLE_DEBUG_C_VAL)
  void OnValueChanged() {
    // Push the value changed event to all listeners.
    if (registered_) {
      CValManager::GetInstance()->PushValueChangedEvent(
          this, CValSpecificValue<T>(value_));
    }
  }
#endif  // ENABLE_DEBUG_C_VAL

  T value_;
  mutable bool registered_;
  mutable scoped_refptr<RefCountedThreadSafeLock> value_lock_refptr_;
};

#if !defined(ENABLE_DEBUG_C_VAL)
// This is a wrapper class that mimics the behavior of the underlying type. It
// does not register with the |CValManager| and does not push value changed
// events.
template <typename T>
class CValStub {
 public:
  CValStub(const std::string& name, const T& initial_value,
           const std::string& description)
      : value_(initial_value) {}
  CValStub(const std::string& name, const std::string& description) {}

  operator T() const { return value_; }

  const CValStub<T>& operator=(const T& rhs) {
    value_ = rhs;
    return *this;
  }
  const CValStub<T>& operator+=(const T& rhs) {
    value_ += rhs;
    return *this;
  }
  const CValStub<T>& operator-=(const T& rhs) {
    value_ -= rhs;
    return *this;
  }

  const CValStub<T>& operator++() {
    ++value_;
    return *this;
  }

  const CValStub<T>& operator--() {
    --value_;
    return *this;
  }

  bool operator<(const T& rhs) const { return value_ < rhs; }
  bool operator>(const T& rhs) const { return value_ > rhs; }
  bool operator==(const T& rhs) const { return value_ == rhs; }

  T value() const { return value_; }

 private:
  T value_;
};
#endif  // ENABLE_DEBUG_C_VAL

}  // namespace CValDetail

class CValPublic {};
class CValDebug {};

template <typename T, typename Visibility = CValDebug>
class CVal {};

template <typename T>
#if defined(ENABLE_DEBUG_C_VAL)
// When ENABLE_DEBUG_C_VAL is defined, CVals with Visibility set to CValDebug
// are tracked through the CVal system.
class CVal<T, CValDebug> : public CValDetail::CValImpl<T> {
  typedef CValDetail::CValImpl<T> CValParent;
#else   // ENABLE_DEBUG_C_VAL
// When ENABLE_DEBUG_C_VAL is not defined, CVals with Visibility set to
// CValDebug are not tracked though the CVal system, and will behave as
// similarly as possible to their underlying types.
class CVal<T, CValDebug> : public CValDetail::CValStub<T> {
  typedef CValDetail::CValStub<T> CValParent;
#endif  // ENABLE_DEBUG_C_VAL

 public:
  CVal(const std::string& name, const T& initial_value,
       const std::string& description)
      : CValParent(name, initial_value, description) {}

  CVal(const std::string& name, const std::string& description)
      : CValParent(name, description) {}

  const CVal& operator=(const T& rhs) {
    CValParent::operator=(rhs);
    return *this;
  }
};

// CVals with visibility set to CValPublic are always tracked though the CVal
// system, regardless of the ENABLE_DEBUG_C_VAL state.
template <typename T>
class CVal<T, CValPublic> : public CValDetail::CValImpl<T> {
  typedef CValDetail::CValImpl<T> CValParent;

 public:
  CVal(const std::string& name, const T& initial_value,
       const std::string& description)
      : CValParent(name, initial_value, description) {}

  CVal(const std::string& name, const std::string& description)
      : CValParent(name, description) {}

  const CVal& operator=(const T& rhs) {
    CValParent::operator=(rhs);
    return *this;
  }
};

}  // namespace base

#endif  // COBALT_BASE_C_VAL_H_
