// Copyright 2014 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.

#ifndef BASE_TEST_METRICS_HISTOGRAM_TESTER_H_
#define BASE_TEST_METRICS_HISTOGRAM_TESTER_H_

#include <map>
#include <memory>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_base.h"
#include "base/time/time.h"

namespace base {

struct Bucket;
class HistogramSamples;

// HistogramTester provides a simple interface for examining histograms, UMA
// or otherwise. Tests can use this interface to verify that histogram data is
// getting logged as intended.
//
// Note: When using this class from a browser test, one might have to call
// SubprocessMetricsProvider::MergeHistogramDeltasForTesting() to sync the
// histogram data between the renderer and browser processes. If it is in a
// content browser test, then content::FetchHistogramsFromChildProcesses()
// should be used to achieve that.
class HistogramTester {
 public:
  using CountsMap = std::map<std::string, HistogramBase::Count>;

  // Takes a snapshot of all current histograms counts.
  HistogramTester();
  ~HistogramTester();

  // We know the exact number of samples in a bucket, and that no other bucket
  // should have samples. Measures the diff from the snapshot taken when this
  // object was constructed.
  void ExpectUniqueSample(const std::string& name,
                          HistogramBase::Sample sample,
                          HistogramBase::Count expected_count) const;
  template <typename T>
  void ExpectUniqueSample(const std::string& name,
                          T sample,
                          HistogramBase::Count expected_count) const {
    ExpectUniqueSample(name, static_cast<HistogramBase::Sample>(sample),
                       expected_count);
  }

  // We know the exact number of samples in a bucket, but other buckets may
  // have samples as well. Measures the diff from the snapshot taken when this
  // object was constructed.
  void ExpectBucketCount(const std::string& name,
                         HistogramBase::Sample sample,
                         HistogramBase::Count expected_count) const;
  template <typename T>
  void ExpectBucketCount(const std::string& name,
                         T sample,
                         HistogramBase::Count expected_count) const {
    ExpectBucketCount(name, static_cast<HistogramBase::Sample>(sample),
                      expected_count);
  }

  // We don't know the values of the samples, but we know how many there are.
  // This measures the diff from the snapshot taken when this object was
  // constructed.
  void ExpectTotalCount(const std::string& name,
                        HistogramBase::Count count) const;

  // We know exact number of samples for buckets corresponding to a time
  // interval. Other intervals may have samples too.
  void ExpectTimeBucketCount(const std::string& name,
                             TimeDelta sample,
                             HistogramBase::Count count) const;

  // Returns a list of all of the buckets recorded since creation of this
  // object, as vector<Bucket>, where the Bucket represents the min boundary of
  // the bucket and the count of samples recorded to that bucket since creation.
  //
  // Example usage, using gMock:
  //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"),
  //               ElementsAre(Bucket(1, 5), Bucket(2, 10), Bucket(3, 5)));
  //
  // If you build the expected list programmatically, you can use ContainerEq:
  //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"),
  //               ContainerEq(expected_buckets));
  //
  // or EXPECT_EQ if you prefer not to depend on gMock, at the expense of a
  // slightly less helpful failure message:
  //   EXPECT_EQ(expected_buckets,
  //             histogram_tester.GetAllSamples("HistogramName"));
  std::vector<Bucket> GetAllSamples(const std::string& name) const;

  // Returns the value of the |sample| bucket for ths histogram |name|.
  HistogramBase::Count GetBucketCount(const std::string& name,
                                      HistogramBase::Sample sample) const;

  // Finds histograms whose names start with |prefix|, and returns them along
  // with the counts of any samples added since the creation of this object.
  // Histograms that are unchanged are omitted from the result. The return value
  // is a map whose keys are the histogram name, and whose values are the sample
  // count.
  //
  // This is useful for cases where the code under test is choosing among a
  // family of related histograms and incrementing one of them. Typically you
  // should pass the result of this function directly to EXPECT_THAT.
  //
  // Example usage, using gmock (which produces better failure messages):
  //   #include "testing/gmock/include/gmock/gmock.h"
  // ...
  //   base::HistogramTester::CountsMap expected_counts;
  //   expected_counts["MyMetric.A"] = 1;
  //   expected_counts["MyMetric.B"] = 1;
  //   EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("MyMetric."),
  //               testing::ContainerEq(expected_counts));
  CountsMap GetTotalCountsForPrefix(const std::string& prefix) const;

  // Access a modified HistogramSamples containing only what has been logged
  // to the histogram since the creation of this object.
  std::unique_ptr<HistogramSamples> GetHistogramSamplesSinceCreation(
      const std::string& histogram_name) const;

  // Dumps all histograms that have had new samples added to them into a string,
  // for debugging purposes. Note: this will dump the entire contents of any
  // modified histograms and not just the modified buckets.
  std::string GetAllHistogramsRecorded() const;

 private:
  // Verifies and asserts that value in the |sample| bucket matches the
  // |expected_count|. The bucket's current value is determined from |samples|
  // and is modified based on the snapshot stored for histogram |name|.
  void CheckBucketCount(const std::string& name,
                        HistogramBase::Sample sample,
                        Histogram::Count expected_count,
                        const HistogramSamples& samples) const;

  // Verifies that the total number of values recorded for the histogram |name|
  // is |expected_count|. This is checked against |samples| minus the snapshot
  // that was taken for |name|.
  void CheckTotalCount(const std::string& name,
                       Histogram::Count expected_count,
                       const HistogramSamples& samples) const;

  // Sets the value for |count| to be the value in the |sample| bucket. The
  // bucket's current value is determined from |samples| and is modified based
  // on the snapshot stored for histogram |name|.
  void GetBucketCountForSamples(const std::string& name,
                                HistogramBase::Sample sample,
                                const HistogramSamples& samples,
                                HistogramBase::Count* count) const;

  // Used to determine the histogram changes made during this instance's
  // lifecycle.
  std::map<std::string, std::unique_ptr<HistogramSamples>> histograms_snapshot_;

  DISALLOW_COPY_AND_ASSIGN(HistogramTester);
};

struct Bucket {
  Bucket(HistogramBase::Sample min, HistogramBase::Count count)
      : min(min), count(count) {}

  bool operator==(const Bucket& other) const;

  HistogramBase::Sample min;
  HistogramBase::Count count;
};

void PrintTo(const Bucket& value, std::ostream* os);

}  // namespace base

#endif  // BASE_TEST_METRICS_HISTOGRAM_TESTER_H_