// Copyright (c) 2012 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 "net/disk_cache/stats_histogram.h"

#include "base/debug/leak_annotations.h"
#include "base/logging.h"
#include "base/metrics/bucket_ranges.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/sample_vector.h"
#include "base/metrics/statistics_recorder.h"
#include "net/disk_cache/stats.h"

namespace disk_cache {

using base::BucketRanges;
using base::Histogram;
using base::HistogramSamples;
using base::SampleVector;
using base::StatisticsRecorder;

StatsHistogram::StatsHistogram(const std::string& name,
                               Sample minimum,
                               Sample maximum,
                               size_t bucket_count,
                               const BucketRanges* ranges,
                               const Stats* stats)
    : Histogram(name, minimum, maximum, bucket_count, ranges),
      stats_(stats) {}

StatsHistogram::~StatsHistogram() {}

// static
void StatsHistogram::InitializeBucketRanges(const Stats* stats,
                                            BucketRanges* ranges) {
  for (size_t i = 0; i < ranges->size(); i++) {
    ranges->set_range(i, stats->GetBucketRange(i));
  }
  ranges->ResetChecksum();
}

StatsHistogram* StatsHistogram::FactoryGet(const std::string& name,
                                           const Stats* stats) {
  Sample minimum = 1;
  Sample maximum = disk_cache::Stats::kDataSizesLength - 1;
  size_t bucket_count = disk_cache::Stats::kDataSizesLength;
  Histogram* histogram = StatisticsRecorder::FindHistogram(name);
  if (!histogram) {
    DCHECK(stats);

    // To avoid racy destruction at shutdown, the following will be leaked.
    BucketRanges* ranges = new BucketRanges(bucket_count + 1);
    InitializeBucketRanges(stats, ranges);
    const BucketRanges* registered_ranges =
        StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);

    // To avoid racy destruction at shutdown, the following will be leaked.
    StatsHistogram* stats_histogram =
        new StatsHistogram(name, minimum, maximum, bucket_count,
                           registered_ranges, stats);
    stats_histogram->SetFlags(kUmaTargetedHistogramFlag);
    histogram = StatisticsRecorder::RegisterOrDeleteDuplicate(stats_histogram);
  }

  DCHECK(base::HISTOGRAM == histogram->GetHistogramType());
  DCHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));

  // We're preparing for an otherwise unsafe upcast by ensuring we have the
  // proper class type.
  StatsHistogram* return_histogram = static_cast<StatsHistogram*>(histogram);
  return return_histogram;
}

scoped_ptr<HistogramSamples> StatsHistogram::SnapshotSamples() const {
  scoped_ptr<SampleVector> samples(new SampleVector(bucket_ranges()));
  stats_->Snapshot(samples.get());

  // Only report UMA data once.
  StatsHistogram* mutable_me = const_cast<StatsHistogram*>(this);
  mutable_me->ClearFlags(kUmaTargetedHistogramFlag);

  return samples.PassAs<HistogramSamples>();
}

Histogram::Inconsistencies StatsHistogram::FindCorruption(
    const HistogramSamples& samples) const {
  return NO_INCONSISTENCIES;  // This class won't monitor inconsistencies.
}

}  // namespace disk_cache
