//===-- Measurement.h -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef __PerfTestDriver__Measurement__
#define __PerfTestDriver__Measurement__

#include "Gauge.h"
#include "MemoryGauge.h"
#include "Metric.h"
#include "Timer.h"

namespace lldb_perf {
template <typename GaugeType, typename Callable> class Measurement {
public:
  Measurement() : m_gauge(), m_callable(), m_metric() {}

  Measurement(Callable callable, const char *name, const char *desc)
      : m_gauge(), m_callable(callable),
        m_metric(Metric<typename GaugeType::ValueType>(name, desc)) {}

  Measurement(const char *name, const char *desc)
      : m_gauge(), m_callable(),
        m_metric(Metric<typename GaugeType::ValueType>(name, desc)) {}

  template <typename GaugeType_Rhs, typename Callable_Rhs>
  Measurement(const Measurement<GaugeType_Rhs, Callable_Rhs> &rhs)
      : m_gauge(rhs.GetGauge()), m_callable(rhs.GetCallable()),
        m_metric(rhs.GetMetric()) {}

  template <typename... Args> void operator()(Args... args) {
    m_gauge.Start();
    m_callable(args...);
    m_metric.Append(m_gauge.Stop());
  }

  virtual const Callable &GetCallable() const { return m_callable; }

  virtual const GaugeType &GetGauge() const { return m_gauge; }

  virtual const Metric<typename GaugeType::ValueType> &GetMetric() const {
    return m_metric;
  }

  void Start() { m_gauge.Start(); }

  typename GaugeType::ValueType Stop() {
    auto value = m_gauge.Stop();
    m_metric.Append(value);
    return value;
  }

  void WriteStartValue(Results &results) {
    auto metric = GetMetric();
    results.GetDictionary().Add(
        metric.GetName(), metric.GetDescription(),
        lldb_perf::GetResult<typename GaugeType::ValueType>(
            NULL, metric.GetStartValue()));
  }

  void WriteStopValue(Results &results) {
    auto metric = GetMetric();
    results.GetDictionary().Add(
        metric.GetName(), metric.GetDescription(),
        lldb_perf::GetResult<typename GaugeType::ValueType>(
            NULL, metric.GetStopValue()));
  }

  void WriteAverageValue(Results &results) {
    auto metric = GetMetric();
    results.GetDictionary().Add(
        metric.GetName(), metric.GetDescription(),
        lldb_perf::GetResult<typename GaugeType::ValueType>(
            NULL, metric.GetAverage()));
  }

  void WriteAverageAndStandardDeviation(Results &results) {
    auto metric = GetMetric();
    auto dictionary =
        (Results::Dictionary *)results.GetDictionary()
            .Add(metric.GetName(), metric.GetDescription(),
                 lldb_perf::GetResult<typename GaugeType::ValueType>(
                     NULL, metric.GetAverage()))
            .get();
    if (dictionary) {
      dictionary->Add("stddev", NULL,
                      lldb_perf::GetResult<typename GaugeType::ValueType>(
                          NULL, metric.GetStandardDeviation()));
    }
  }

  void WriteStandardDeviation(Results &results) {
    auto metric = GetMetric();
    results.GetDictionary().Add(
        metric.GetName(), metric.GetDescription(),
        lldb_perf::GetResult<typename GaugeType::ValueType>(
            NULL, metric.GetStandardDeviation()));
  }

protected:
  GaugeType m_gauge;
  Callable m_callable;
  Metric<typename GaugeType::ValueType> m_metric;
};

template <typename Callable>
class TimeMeasurement : public Measurement<TimeGauge, Callable> {
public:
  TimeMeasurement() : Measurement<TimeGauge, Callable>() {}

  TimeMeasurement(Callable callable, const char *name = NULL,
                  const char *descr = NULL)
      : Measurement<TimeGauge, Callable>(callable, name, descr) {}

  template <typename Callable_Rhs>
  TimeMeasurement(const TimeMeasurement<Callable_Rhs> &rhs)
      : Measurement<TimeGauge, Callable>(rhs) {}

  template <typename GaugeType_Rhs, typename Callable_Rhs>
  TimeMeasurement(const Measurement<GaugeType_Rhs, Callable_Rhs> &rhs)
      : Measurement<GaugeType_Rhs, Callable_Rhs>(rhs) {}

  template <typename... Args> void operator()(Args... args) {
    Measurement<TimeGauge, Callable>::operator()(args...);
  }
};

template <typename Callable>
class MemoryMeasurement : public Measurement<MemoryGauge, Callable> {
public:
  MemoryMeasurement() : Measurement<MemoryGauge, Callable>() {}

  MemoryMeasurement(Callable callable, const char *name, const char *descr)
      : Measurement<MemoryGauge, Callable>(callable, name, descr) {}

  MemoryMeasurement(const char *name, const char *descr)
      : Measurement<MemoryGauge, Callable>(name, descr) {}

  template <typename Callable_Rhs>
  MemoryMeasurement(const MemoryMeasurement<Callable_Rhs> &rhs)
      : Measurement<MemoryGauge, Callable>(rhs) {}

  template <typename GaugeType_Rhs, typename Callable_Rhs>
  MemoryMeasurement(const Measurement<GaugeType_Rhs, Callable_Rhs> &rhs)
      : Measurement<GaugeType_Rhs, Callable_Rhs>(rhs) {}

  template <typename... Args> void operator()(Args... args) {
    Measurement<MemoryGauge, Callable>::operator()(args...);
  }
};
}

#endif /* defined(__PerfTestDriver__Measurement__) */
