// 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/android/record_histogram.h"

#include <stdint.h>

#include <map>
#include <string>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "jni/RecordHistogram_jni.h"

namespace base {
namespace android {
namespace {

// Simple thread-safe wrapper for caching histograms. This avoids
// relatively expensive JNI string translation for each recording.
class HistogramCache {
 public:
  HistogramCache() {}

  std::string HistogramConstructionParamsToString(HistogramBase* histogram) {
    std::string params_str = histogram->histogram_name();
    switch (histogram->GetHistogramType()) {
      case HISTOGRAM:
      case LINEAR_HISTOGRAM:
      case BOOLEAN_HISTOGRAM:
      case CUSTOM_HISTOGRAM: {
        Histogram* hist = static_cast<Histogram*>(histogram);
        params_str += StringPrintf("/%d/%d/%d", hist->declared_min(),
                                   hist->declared_max(), hist->bucket_count());
        break;
      }
      case SPARSE_HISTOGRAM:
        break;
    }
    return params_str;
  }

  void CheckHistogramArgs(JNIEnv* env,
                          jstring j_histogram_name,
                          int32_t expected_min,
                          int32_t expected_max,
                          uint32_t expected_bucket_count,
                          HistogramBase* histogram) {
    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    bool valid_arguments = Histogram::InspectConstructionArguments(
        histogram_name, &expected_min, &expected_max, &expected_bucket_count);
    DCHECK(valid_arguments);
    DCHECK(histogram->HasConstructionArguments(expected_min, expected_max,
                                               expected_bucket_count))
        << histogram_name << "/" << expected_min << "/" << expected_max << "/"
        << expected_bucket_count << " vs. "
        << HistogramConstructionParamsToString(histogram);
  }

  HistogramBase* BooleanHistogram(JNIEnv* env,
                                  jstring j_histogram_name,
                                  jlong j_histogram_key) {
    DCHECK(j_histogram_name);
    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
    if (histogram)
      return histogram;

    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    histogram = BooleanHistogram::FactoryGet(
        histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
    return histogram;
  }

  HistogramBase* EnumeratedHistogram(JNIEnv* env,
                                     jstring j_histogram_name,
                                     jlong j_histogram_key,
                                     jint j_boundary) {
    DCHECK(j_histogram_name);
    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
    int32_t boundary = static_cast<int32_t>(j_boundary);
    if (histogram) {
      CheckHistogramArgs(env, j_histogram_name, 1, boundary, boundary + 1,
                         histogram);
      return histogram;
    }

    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    histogram =
        LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
                                    HistogramBase::kUmaTargetedHistogramFlag);
    return histogram;
  }

  HistogramBase* CustomCountHistogram(JNIEnv* env,
                                      jstring j_histogram_name,
                                      jlong j_histogram_key,
                                      jint j_min,
                                      jint j_max,
                                      jint j_num_buckets) {
    DCHECK(j_histogram_name);
    int32_t min = static_cast<int32_t>(j_min);
    int32_t max = static_cast<int32_t>(j_max);
    int32_t num_buckets = static_cast<int32_t>(j_num_buckets);
    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
    if (histogram) {
      CheckHistogramArgs(env, j_histogram_name, min, max, num_buckets,
                         histogram);
      return histogram;
    }

    DCHECK_GE(min, 1) << "The min expected sample must be >= 1";

    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    histogram =
        Histogram::FactoryGet(histogram_name, min, max, num_buckets,
                              HistogramBase::kUmaTargetedHistogramFlag);
    return histogram;
  }

  HistogramBase* LinearCountHistogram(JNIEnv* env,
                                      jstring j_histogram_name,
                                      jlong j_histogram_key,
                                      jint j_min,
                                      jint j_max,
                                      jint j_num_buckets) {
    DCHECK(j_histogram_name);
    int32_t min = static_cast<int32_t>(j_min);
    int32_t max = static_cast<int32_t>(j_max);
    int32_t num_buckets = static_cast<int32_t>(j_num_buckets);
    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
    if (histogram) {
      CheckHistogramArgs(env, j_histogram_name, min, max, num_buckets,
                         histogram);
      return histogram;
    }

    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    histogram =
        LinearHistogram::FactoryGet(histogram_name, min, max, num_buckets,
                                    HistogramBase::kUmaTargetedHistogramFlag);
    return histogram;
  }

  HistogramBase* SparseHistogram(JNIEnv* env,
                                 jstring j_histogram_name,
                                 jlong j_histogram_key) {
    DCHECK(j_histogram_name);
    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
    if (histogram)
      return histogram;

    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    histogram = SparseHistogram::FactoryGet(
        histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
    return histogram;
  }

  HistogramBase* CustomTimesHistogram(JNIEnv* env,
                                      jstring j_histogram_name,
                                      jlong j_histogram_key,
                                      jint j_min,
                                      jint j_max,
                                      jint j_bucket_count) {
    DCHECK(j_histogram_name);
    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
    int32_t min = static_cast<int32_t>(j_min);
    int32_t max = static_cast<int32_t>(j_max);
    int32_t bucket_count = static_cast<int32_t>(j_bucket_count);
    if (histogram) {
      CheckHistogramArgs(env, j_histogram_name, min, max, bucket_count,
                         histogram);
      return histogram;
    }

    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
    // This intentionally uses FactoryGet and not FactoryTimeGet. FactoryTimeGet
    // is just a convenience for constructing the underlying Histogram with
    // TimeDelta arguments.
    histogram = Histogram::FactoryGet(histogram_name, min, max, bucket_count,
                                      HistogramBase::kUmaTargetedHistogramFlag);
    return histogram;
  }

 private:
  // Convert a jlong |histogram_key| from Java to a HistogramBase* via a cast.
  // The Java side caches these in a map (see RecordHistogram.java), which is
  // safe to do since C++ Histogram objects are never freed.
  static HistogramBase* HistogramFromKey(jlong j_histogram_key) {
    return reinterpret_cast<HistogramBase*>(j_histogram_key);
  }

  DISALLOW_COPY_AND_ASSIGN(HistogramCache);
};

LazyInstance<HistogramCache>::Leaky g_histograms;

}  // namespace

jlong RecordBooleanHistogram(JNIEnv* env,
                             const JavaParamRef<jclass>& clazz,
                             const JavaParamRef<jstring>& j_histogram_name,
                             jlong j_histogram_key,
                             jboolean j_sample) {
  bool sample = static_cast<bool>(j_sample);
  HistogramBase* histogram = g_histograms.Get().BooleanHistogram(
      env, j_histogram_name, j_histogram_key);
  histogram->AddBoolean(sample);
  return reinterpret_cast<jlong>(histogram);
}

jlong RecordEnumeratedHistogram(JNIEnv* env,
                                const JavaParamRef<jclass>& clazz,
                                const JavaParamRef<jstring>& j_histogram_name,
                                jlong j_histogram_key,
                                jint j_sample,
                                jint j_boundary) {
  int sample = static_cast<int>(j_sample);

  HistogramBase* histogram = g_histograms.Get().EnumeratedHistogram(
      env, j_histogram_name, j_histogram_key, j_boundary);
  histogram->Add(sample);
  return reinterpret_cast<jlong>(histogram);
}

jlong RecordCustomCountHistogram(JNIEnv* env,
                                 const JavaParamRef<jclass>& clazz,
                                 const JavaParamRef<jstring>& j_histogram_name,
                                 jlong j_histogram_key,
                                 jint j_sample,
                                 jint j_min,
                                 jint j_max,
                                 jint j_num_buckets) {
  int sample = static_cast<int>(j_sample);

  HistogramBase* histogram = g_histograms.Get().CustomCountHistogram(
      env, j_histogram_name, j_histogram_key, j_min, j_max, j_num_buckets);
  histogram->Add(sample);
  return reinterpret_cast<jlong>(histogram);
}

jlong RecordLinearCountHistogram(JNIEnv* env,
                                 const JavaParamRef<jclass>& clazz,
                                 const JavaParamRef<jstring>& j_histogram_name,
                                 jlong j_histogram_key,
                                 jint j_sample,
                                 jint j_min,
                                 jint j_max,
                                 jint j_num_buckets) {
  int sample = static_cast<int>(j_sample);

  HistogramBase* histogram = g_histograms.Get().LinearCountHistogram(
      env, j_histogram_name, j_histogram_key, j_min, j_max, j_num_buckets);
  histogram->Add(sample);
  return reinterpret_cast<jlong>(histogram);
}

jlong RecordSparseHistogram(JNIEnv* env,
                            const JavaParamRef<jclass>& clazz,
                            const JavaParamRef<jstring>& j_histogram_name,
                            jlong j_histogram_key,
                            jint j_sample) {
  int sample = static_cast<int>(j_sample);
  HistogramBase* histogram = g_histograms.Get().SparseHistogram(
      env, j_histogram_name, j_histogram_key);
  histogram->Add(sample);
  return reinterpret_cast<jlong>(histogram);
}

jlong RecordCustomTimesHistogramMilliseconds(
    JNIEnv* env,
    const JavaParamRef<jclass>& clazz,
    const JavaParamRef<jstring>& j_histogram_name,
    jlong j_histogram_key,
    jint j_duration,
    jint j_min,
    jint j_max,
    jint j_num_buckets) {
  HistogramBase* histogram = g_histograms.Get().CustomTimesHistogram(
      env, j_histogram_name, j_histogram_key, j_min, j_max, j_num_buckets);
  histogram->AddTime(
      TimeDelta::FromMilliseconds(static_cast<int64_t>(j_duration)));
  return reinterpret_cast<jlong>(histogram);
}

void Initialize(JNIEnv* env, const JavaParamRef<jclass>&) {
  StatisticsRecorder::Initialize();
}

// This backs a Java test util for testing histograms -
// MetricsUtils.HistogramDelta. It should live in a test-specific file, but we
// currently can't have test-specific native code packaged in test-specific Java
// targets - see http://crbug.com/415945.
jint GetHistogramValueCountForTesting(
    JNIEnv* env,
    const JavaParamRef<jclass>& clazz,
    const JavaParamRef<jstring>& histogram_name,
    jint sample) {
  HistogramBase* histogram = StatisticsRecorder::FindHistogram(
      android::ConvertJavaStringToUTF8(env, histogram_name));
  if (histogram == nullptr) {
    // No samples have been recorded for this histogram (yet?).
    return 0;
  }

  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
  return samples->GetCount(static_cast<int>(sample));
}

bool RegisterRecordHistogram(JNIEnv* env) {
  return RegisterNativesImpl(env);
}

}  // namespace android
}  // namespace base
