// 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 "chrome/browser/ui/webui/metrics_handler.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"

using base::ListValue;
using base::UserMetricsAction;
using content::WebContents;

MetricsHandler::MetricsHandler() {}
MetricsHandler::~MetricsHandler() {}

void MetricsHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "metricsHandler:recordAction",
      base::BindRepeating(&MetricsHandler::HandleRecordAction,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "metricsHandler:recordInHistogram",
      base::BindRepeating(&MetricsHandler::HandleRecordInHistogram,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "metricsHandler:recordBooleanHistogram",
      base::BindRepeating(&MetricsHandler::HandleRecordBooleanHistogram,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "metricsHandler:recordTime",
      base::BindRepeating(&MetricsHandler::HandleRecordTime,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "metricsHandler:logEventTime",
      base::BindRepeating(&MetricsHandler::HandleLogEventTime,
                          base::Unretained(this)));
}

void MetricsHandler::HandleRecordAction(const base::ListValue* args) {
  std::string string_action = base::UTF16ToUTF8(ExtractStringValue(args));
  base::RecordComputedAction(string_action);
}

void MetricsHandler::HandleRecordInHistogram(const base::ListValue* args) {
  std::string histogram_name;
  double value;
  double boundary_value;
  if (!args->GetString(0, &histogram_name) ||
      !args->GetDouble(1, &value) ||
      !args->GetDouble(2, &boundary_value)) {
    NOTREACHED();
    return;
  }

  int int_value = static_cast<int>(value);
  int int_boundary_value = static_cast<int>(boundary_value);
  if (int_boundary_value >= 4000 ||
      int_value > int_boundary_value ||
      int_value < 0) {
    NOTREACHED();
    return;
  }

  int bucket_count = int_boundary_value;
  while (bucket_count >= 100) {
    bucket_count /= 10;
  }

  // As |histogram_name| may change between calls, the UMA_HISTOGRAM_ENUMERATION
  // macro cannot be used here.
  base::HistogramBase* counter =
      base::LinearHistogram::FactoryGet(
          histogram_name, 1, int_boundary_value, bucket_count + 1,
          base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->Add(int_value);
}

void MetricsHandler::HandleRecordBooleanHistogram(const base::ListValue* args) {
  std::string histogram_name;
  bool value;
  if (!args->GetString(0, &histogram_name) || !args->GetBoolean(1, &value)) {
    NOTREACHED();
    return;
  }

  base::HistogramBase* counter = base::BooleanHistogram::FactoryGet(
      histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->AddBoolean(value);
}

void MetricsHandler::HandleRecordTime(const base::ListValue* args) {
  std::string histogram_name;
  double value;

  if (!args->GetString(0, &histogram_name) ||
      !args->GetDouble(1, &value) ||
      value < 0) {
    NOTREACHED();
    return;
  }

  base::TimeDelta time_value = base::TimeDelta::FromMilliseconds(value);

  base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
      histogram_name, base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSeconds(10), 50,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->AddTime(time_value);
}

void MetricsHandler::HandleLogEventTime(const base::ListValue* args) {
  std::string event_name = base::UTF16ToUTF8(ExtractStringValue(args));
  WebContents* tab = web_ui()->GetWebContents();

  // Not all new tab pages get timed. In those cases, we don't have a
  // new_tab_start_time_.
  CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(tab);
  if (core_tab_helper->new_tab_start_time().is_null())
    return;

  base::TimeDelta duration =
      base::TimeTicks::Now() - core_tab_helper->new_tab_start_time();

  if (event_name == "Tab.NewTabScriptStart") {
    UMA_HISTOGRAM_TIMES("Tab.NewTabScriptStart", duration);
  } else if (event_name == "Tab.NewTabDOMContentLoaded") {
    UMA_HISTOGRAM_TIMES("Tab.NewTabDOMContentLoaded", duration);
  } else if (event_name == "Tab.NewTabOnload") {
    UMA_HISTOGRAM_TIMES("Tab.NewTabOnload", duration);
    // The new tab page has finished loading; reset it.
    CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(tab);
    core_tab_helper->set_new_tab_start_time(base::TimeTicks());
  } else {
    NOTREACHED();
  }
}
