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

#include "base/test/histogram_tester.h"

#include <stddef.h>

#include "base/metrics/histogram.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/metrics_hashes.h"
#include "base/metrics/sample_map.h"
#include "base/metrics/statistics_recorder.h"
#include "base/strings/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

HistogramTester::HistogramTester() {
  // Record any histogram data that exists when the object is created so it can
  // be subtracted later.
  for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
    histograms_snapshot_[histogram->histogram_name()] =
        histogram->SnapshotSamples();
  }
}

HistogramTester::~HistogramTester() = default;

void HistogramTester::ExpectUniqueSample(
    const std::string& name,
    HistogramBase::Sample sample,
    HistogramBase::Count expected_count) const {
  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
  EXPECT_NE(nullptr, histogram) << "Histogram \"" << name
                                << "\" does not exist.";

  if (histogram) {
    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
    CheckBucketCount(name, sample, expected_count, *samples);
    CheckTotalCount(name, expected_count, *samples);
  }
}

void HistogramTester::ExpectBucketCount(
    const std::string& name,
    HistogramBase::Sample sample,
    HistogramBase::Count expected_count) const {
  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
  EXPECT_NE(nullptr, histogram) << "Histogram \"" << name
                                << "\" does not exist.";

  if (histogram) {
    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
    CheckBucketCount(name, sample, expected_count, *samples);
  }
}

void HistogramTester::ExpectTotalCount(const std::string& name,
                                       HistogramBase::Count count) const {
  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
  if (histogram) {
    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
    CheckTotalCount(name, count, *samples);
  } else {
    // No histogram means there were zero samples.
    EXPECT_EQ(count, 0) << "Histogram \"" << name << "\" does not exist.";
  }
}

void HistogramTester::ExpectTimeBucketCount(const std::string& name,
                                            TimeDelta sample,
                                            HistogramBase::Count count) const {
  ExpectBucketCount(name, sample.InMilliseconds(), count);
}

std::vector<Bucket> HistogramTester::GetAllSamples(
    const std::string& name) const {
  std::vector<Bucket> samples;
  std::unique_ptr<HistogramSamples> snapshot =
      GetHistogramSamplesSinceCreation(name);
  if (snapshot) {
    for (auto it = snapshot->Iterator(); !it->Done(); it->Next()) {
      HistogramBase::Sample sample;
      HistogramBase::Count count;
      it->Get(&sample, nullptr, &count);
      samples.push_back(Bucket(sample, count));
    }
  }
  return samples;
}

HistogramBase::Count HistogramTester::GetBucketCount(
    const std::string& name,
    HistogramBase::Sample sample) const {
  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
  EXPECT_NE(nullptr, histogram)
      << "Histogram \"" << name << "\" does not exist.";
  HistogramBase::Count count = 0;
  if (histogram) {
    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
    GetBucketCountForSamples(name, sample, *samples, &count);
  }
  return count;
}

void HistogramTester::GetBucketCountForSamples(
    const std::string& name,
    HistogramBase::Sample sample,
    const HistogramSamples& samples,
    HistogramBase::Count* count) const {
  *count = samples.GetCount(sample);
  auto histogram_data = histograms_snapshot_.find(name);
  if (histogram_data != histograms_snapshot_.end())
    *count -= histogram_data->second->GetCount(sample);
}

HistogramTester::CountsMap HistogramTester::GetTotalCountsForPrefix(
    const std::string& prefix) const {
  EXPECT_TRUE(prefix.find('.') != std::string::npos)
      << "|prefix| ought to contain at least one period, to avoid matching too"
      << " many histograms.";

  CountsMap result;

  // Find candidate matches by using the logic built into GetSnapshot().
  for (const HistogramBase* histogram : StatisticsRecorder::GetHistograms()) {
    if (!StartsWith(histogram->histogram_name(), prefix,
                    CompareCase::SENSITIVE)) {
      continue;
    }
    std::unique_ptr<HistogramSamples> new_samples =
        GetHistogramSamplesSinceCreation(histogram->histogram_name());
    // Omit unchanged histograms from the result.
    if (new_samples->TotalCount()) {
      result[histogram->histogram_name()] = new_samples->TotalCount();
    }
  }
  return result;
}

std::unique_ptr<HistogramSamples>
HistogramTester::GetHistogramSamplesSinceCreation(
    const std::string& histogram_name) const {
  HistogramBase* histogram = StatisticsRecorder::FindHistogram(histogram_name);
  // Whether the histogram exists or not may not depend on the current test
  // calling this method, but rather on which tests ran before and possibly
  // generated a histogram or not (see http://crbug.com/473689). To provide a
  // response which is independent of the previously run tests, this method
  // creates empty samples in the absence of the histogram, rather than
  // returning null.
  if (!histogram) {
    return std::unique_ptr<HistogramSamples>(
        new SampleMap(HashMetricName(histogram_name)));
  }
  std::unique_ptr<HistogramSamples> named_samples =
      histogram->SnapshotSamples();
  auto original_samples_it = histograms_snapshot_.find(histogram_name);
  if (original_samples_it != histograms_snapshot_.end())
    named_samples->Subtract(*original_samples_it->second.get());
  return named_samples;
}

void HistogramTester::CheckBucketCount(const std::string& name,
                                       HistogramBase::Sample sample,
                                       HistogramBase::Count expected_count,
                                       const HistogramSamples& samples) const {
  int actual_count;
  GetBucketCountForSamples(name, sample, samples, &actual_count);

  EXPECT_EQ(expected_count, actual_count)
      << "Histogram \"" << name
      << "\" does not have the right number of samples (" << expected_count
      << ") in the expected bucket (" << sample << "). It has (" << actual_count
      << ").";
}

void HistogramTester::CheckTotalCount(const std::string& name,
                                      HistogramBase::Count expected_count,
                                      const HistogramSamples& samples) const {
  int actual_count = samples.TotalCount();
  auto histogram_data = histograms_snapshot_.find(name);
  if (histogram_data != histograms_snapshot_.end())
    actual_count -= histogram_data->second->TotalCount();

  EXPECT_EQ(expected_count, actual_count)
      << "Histogram \"" << name
      << "\" does not have the right total number of samples ("
      << expected_count << "). It has (" << actual_count << ").";
}

bool Bucket::operator==(const Bucket& other) const {
  return min == other.min && count == other.count;
}

void PrintTo(const Bucket& bucket, std::ostream* os) {
  *os << "Bucket " << bucket.min << ": " << bucket.count;
}

}  // namespace base
