// Copyright 2013 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/chromeos/swap_metrics.h"

#include <string>
#include <vector>

#include "ash/shell.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/cancellation_flag.h"
#include "base/sys_info.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/events/event.h"

using base::FilePath;

namespace chromeos {
namespace {

// Time delays for metrics collections, starting after an interesting UI event.
// Times are relative to the UI event. Start with zero to record the initial
// state of the metrics immediately.
const int kMetricsDelayMs[] = { 0, 100, 300, 1000, 3000 };

}  // namespace

///////////////////////////////////////////////////////////////////////////////

// Runs in the blocking thread pool to load metrics and record them.
// Reads data about CPU utilization and swap activity from the /proc and /sys
// file systems. Owned by SwapMetrics on the UI thread.
class SwapMetrics::Backend : public base::RefCountedThreadSafe<Backend> {
 public:
  explicit Backend(const std::string& reason);

  // Records one set of statistics for |time_index| after the interesting
  // event. May trigger another delayed task to record more statistics.
  void RecordMetricsOnBlockingPool(size_t time_index);

  // Sets the thread-safe cancellation flag.
  void CancelOnUIThread() { cancelled_.Set(); }

 private:
  friend class base::RefCountedThreadSafe<Backend>;

  virtual ~Backend();

  // Extracts a field value from a list of name-value pairs
  // in a file (typically a /proc or /sys file). Returns false
  // if the field is not found, or for other errors.
  bool GetFieldFromKernelOutput(const std::string& path,
                                const std::string& field,
                                int64* value);

  // Reads a file whose content is a single line, and returns its content as a
  // list of tokens. |expected_tokens_count| is the expected number of tokens.
  // |delimiters| is a string containing characters that may appear between
  // tokens. Returns true on success, false otherwise.
  bool TokenizeOneLineFile(const std::string& path,
                           size_t expected_tokens_count,
                           const std::string& delimiters,
                           std::vector<std::string>* tokens);

  // Retrieve various system metrics. Return true on success.
  bool GetMeminfoField(const std::string& field, int64* value);
  bool GetUptime(double* uptime_secs, double* idle_time_secs);
  bool GetPageFaults(int64* page_faults);

  // Record histogram samples.
  void RecordFaultsHistogramSample(int faults,
                                   const std::string& reason,
                                   int swap_group,
                                   int time_index);
  void RecordCpuHistogramSample(int cpu,
                                const std::string& reason,
                                int swap_group,
                                int time_index);

  // Cancellation flag that can be written from the UI thread (which owns this
  // object) and read from any thread.
  base::CancellationFlag cancelled_;

  // Data initialized once and shared by all instances of this class.
  static bool first_time_;
  static int64 swap_total_kb_;
  static int number_of_cpus_;

  // Values at the beginning of each sampling interval.
  double last_uptime_secs_;
  double last_idle_time_secs_;
  int64 last_page_faults_;

  // Swap group for a set of samples, chosen at the beginning of the set.
  int swap_group_;

  // Reason for sampling.
  const std::string reason_;

  DISALLOW_COPY_AND_ASSIGN(Backend);
};

// static
bool SwapMetrics::Backend::first_time_ = true;
// static
int64 SwapMetrics::Backend::swap_total_kb_ = 0;
// static
int SwapMetrics::Backend::number_of_cpus_ = 0;

SwapMetrics::Backend::Backend(const std::string& reason)
    : last_uptime_secs_(0.0),
      last_idle_time_secs_(0.0),
      last_page_faults_(0),
      swap_group_(0),
      reason_(reason) {
}

SwapMetrics::Backend::~Backend() {
}

void SwapMetrics::Backend::RecordMetricsOnBlockingPool(size_t time_index) {
  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
  // Another UI event might have occurred. Don't run this metrics collection
  // and don't post another task. This object's refcount will drop and it will
  // be deleted when the next backend is created on the UI thread.
  if (cancelled_.IsSet())
    return;
  DVLOG(1) << "RecordMetricsInBlockingPool " << time_index;

  // At init time, get the number of cpus and the total swap. The number of cpus
  // is necessary because the idle time reported is the sum of the idle
  // times of all cpus.
  //
  // When an event occurs:
  // - At time t_0, save the initial values for uptime, idle_time, page_faults,
  //   and swap used.
  //
  // - At time t_i, compute cpu utilization as a fraction (1 = fully utilized):
  //  utilization =
  //      1 - (idle_time_i - idle_time_0) / (uptime_i - uptime_0) / ncpus
  //
  // then UMA-report it in the right swap group. Do the same for page faults.

  if (first_time_) {
    first_time_ = false;
    number_of_cpus_ = base::SysInfo::NumberOfProcessors();
    // Avoid divide by zero in case of errors.
    if (number_of_cpus_ == 0)
      number_of_cpus_ = 1;
    GetMeminfoField("SwapTotal:", &swap_total_kb_);
  }

  if (time_index == 0) {
    // Record baseline data.
    GetUptime(&last_uptime_secs_, &last_idle_time_secs_);
    GetPageFaults(&last_page_faults_);
    int64 swap_free_kb = 0;
    GetMeminfoField("SwapFree:", &swap_free_kb);
    int swap_percent = swap_total_kb_ > 0
        ? (swap_total_kb_ - swap_free_kb) * 100 / swap_total_kb_
        : 0;
    if (swap_percent < 10)
      swap_group_ = 0;
    else if (swap_percent < 30)
      swap_group_ = 1;
    else if (swap_percent < 60)
      swap_group_ = 2;
    else
      swap_group_ = 3;
  } else {
    int64 page_faults = 0;
    double idle_time_secs = 0.0;
    double uptime_secs = 0.0;
    GetUptime(&uptime_secs, &idle_time_secs);
    GetPageFaults(&page_faults);
    double delta_time_secs = uptime_secs - last_uptime_secs_;
    // Unexpected, but not worth agonizing over it.
    if (delta_time_secs == 0)
      return;

    int cpu = (1.0 - (idle_time_secs - last_idle_time_secs_) /
               delta_time_secs / number_of_cpus_) * 100;
    int faults_per_sec = (page_faults - last_page_faults_) / delta_time_secs;

    RecordCpuHistogramSample(cpu, reason_, swap_group_, time_index);
    RecordFaultsHistogramSample(faults_per_sec, reason_,
                                swap_group_, time_index);

    last_uptime_secs_ = uptime_secs;
    last_page_faults_ = page_faults;
    last_idle_time_secs_ = idle_time_secs;
  }

  // Check if another metrics recording is needed.
  if (++time_index >= arraysize(kMetricsDelayMs))
    return;
  PostTaskRecordMetrics(
      scoped_refptr<Backend>(this),
      time_index,
      kMetricsDelayMs[time_index] - kMetricsDelayMs[time_index - 1]);
}

void SwapMetrics::Backend::RecordFaultsHistogramSample(
    int faults,
    const std::string& reason,
    int swap_group,
    int time_index) {
  std::string name =
      base::StringPrintf("Platform.SwapJank.%s.Faults.Swap%d.Time%d",
                         reason.c_str(),
                         swap_group,
                         time_index);
  const int kMinimumBucket = 10;
  const int kMaximumBucket = 200000;
  const size_t kBucketCount = 50;
  base::HistogramBase* counter =
      base::Histogram::FactoryGet(name,
                                  kMinimumBucket,
                                  kMaximumBucket,
                                  kBucketCount,
                                  base::Histogram::kUmaTargetedHistogramFlag);
  counter->Add(faults);
}

void SwapMetrics::Backend::RecordCpuHistogramSample(int cpu,
                                                    const std::string& reason,
                                                    int swap_group,
                                                    int time_index) {
  std::string name =
      base::StringPrintf("Platform.SwapJank.%s.Cpu.Swap%d.Time%d",
                         reason.c_str(),
                         swap_group,
                         time_index);
  const int kMinimumBucket = 0;
  const int kMaximumBucket = 101;
  const size_t kBucketCount = 102;
  base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
      name,
      kMinimumBucket,
      kMaximumBucket,
      kBucketCount,
      base::Histogram::kUmaTargetedHistogramFlag);
  counter->Add(cpu);
}

// Extracts a field value from a list of name-value pairs
// in a file (typically a /proc or /sys file). Returns false
// if the field is not found, or for other errors.
bool SwapMetrics::Backend::GetFieldFromKernelOutput(const std::string& path,
                                                    const std::string& field,
                                                    int64* value) {
  std::string file_content;
  if (!file_util::ReadFileToString(FilePath(path), &file_content)) {
    LOG(WARNING) << "Cannot read " << path;
    return false;
  }
  std::vector<std::string> lines;
  size_t line_count = Tokenize(file_content, "\n", &lines);
  if (line_count < 2) {
    LOG(WARNING) << "Error breaking " << path << " into lines";
    return false;
  }
  for (size_t i = 0; i < line_count; ++i) {
    std::vector<std::string> tokens;
    size_t token_count = Tokenize(lines[i], " ", &tokens);
    if (token_count < 2) {
      LOG(WARNING) << "Unexpected line: " << lines[i];
      return false;
    }
    if (tokens[0].compare(field) != 0)
      continue;
    if (!base::StringToInt64(tokens[1], value)) {
      LOG(WARNING) << "Cannot convert " << tokens[1] << " to int";
      return false;
    }
    return true;
  }
  LOG(WARNING) << "could not find field " << field;
  return false;
}

bool SwapMetrics::Backend::TokenizeOneLineFile(const std::string& path,
                                               size_t expected_tokens_count,
                                               const std::string& delimiters,
                                               std::vector<std::string>*
                                               tokens) {
  std::string file_content;
  if (!file_util::ReadFileToString(FilePath(path), &file_content)) {
    LOG(WARNING) << "cannot read " << path;
    return false;
  }
  size_t tokens_count = Tokenize(file_content, delimiters, tokens);
  if (tokens_count != expected_tokens_count) {
    LOG(WARNING) << "unexpected content of " << path << ": " << file_content;
    return false;
  }
  return true;
}

bool SwapMetrics::Backend::GetMeminfoField(const std::string& name,
                                           int64* value) {
  return GetFieldFromKernelOutput("/proc/meminfo", name, value);
}

bool SwapMetrics::Backend::GetUptime(double* uptime_secs,
                                     double* idle_time_secs) {
  // Get the time since boot.
  const char kUptimePath[] = "/proc/uptime";
  std::vector<std::string> tokens;
  if (!TokenizeOneLineFile(kUptimePath, 2, " \n", &tokens))
    return false;

  if (!base::StringToDouble(tokens[0], uptime_secs)) {
    LOG(WARNING) << "cannot convert " << tokens[0] << " to double";
    return false;
  }

  // Get the idle time since boot. The number available in /proc/stat is more
  // precise, but this one should be good enough.
  if (!base::StringToDouble(tokens[1], idle_time_secs)) {
    LOG(WARNING) << "cannot convert " << tokens[0] << " to double";
    return false;
  }
  return true;
}

bool SwapMetrics::Backend::GetPageFaults(int64* page_faults) {
  // Get number of page faults.
  return GetFieldFromKernelOutput("/proc/vmstat", "pgmajfault", page_faults);
}

///////////////////////////////////////////////////////////////////////////////

SwapMetrics::SwapMetrics() : browser_(NULL) {
  ash::Shell::GetInstance()->AddPreTargetHandler(this);
  BrowserList::AddObserver(this);
}

SwapMetrics::~SwapMetrics() {
  if (backend_.get())
    backend_->CancelOnUIThread();
  ash::Shell::GetInstance()->RemovePreTargetHandler(this);
  BrowserList::RemoveObserver(this);
  SetBrowser(NULL);
}

void SwapMetrics::OnBrowserRemoved(Browser* browser) {
  if (browser_ == browser)
    SetBrowser(NULL);
}

void SwapMetrics::OnBrowserSetLastActive(Browser* browser) {
  if (browser && browser->type() == Browser::TYPE_TABBED)
    SetBrowser(browser);
  else
    SetBrowser(NULL);
}

void SwapMetrics::ActiveTabChanged(content::WebContents* old_contents,
                                   content::WebContents* new_contents,
                                   int index,
                                   int reason) {
  // Only measure tab switches, not tabs being replaced with new contents.
  if (reason != TabStripModelObserver::CHANGE_REASON_USER_GESTURE)
    return;
  DVLOG(1) << "ActiveTabChanged";
  StartMetricsCollection("TabSwitch");
}

// This exists primarily for debugging on desktop builds.
void SwapMetrics::OnMouseEvent(ui::MouseEvent* event) {
  if (event->type() != ui::ET_MOUSEWHEEL)
    return;
  DVLOG(1) << "OnMouseEvent";
  StartMetricsCollection("Scroll");
}

void SwapMetrics::OnScrollEvent(ui::ScrollEvent* event) {
  if (event->type() != ui::ET_SCROLL &&
      event->type() != ui::ET_SCROLL_FLING_START)
    return;
  DVLOG(1) << "OnScrollEvent";
  StartMetricsCollection("Scroll");
}

// static
void SwapMetrics::PostTaskRecordMetrics(scoped_refptr<Backend> backend,
                                        size_t time_index,
                                        int delay_ms) {
  // Don't block shutdown on these tasks, as UMA will be disappearing.
  scoped_refptr<base::TaskRunner> runner =
      content::BrowserThread::GetBlockingPool()->
          GetTaskRunnerWithShutdownBehavior(
                base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
  runner->PostDelayedTask(
      FROM_HERE,
      base::Bind(&SwapMetrics::Backend::RecordMetricsOnBlockingPool,
                 backend,
                 time_index),
      base::TimeDelta::FromMilliseconds(delay_ms));
}

void SwapMetrics::StartMetricsCollection(const std::string& reason) {
  // Cancel any existing metrics run.
  if (backend_.get())
    backend_->CancelOnUIThread();
  backend_ = new Backend(reason);
  PostTaskRecordMetrics(backend_, 0, kMetricsDelayMs[0]);
}

void SwapMetrics::SetBrowser(Browser* browser) {
  if (browser_ == browser)
    return;
  if (browser_)
    browser_->tab_strip_model()->RemoveObserver(this);
  browser_ = browser;
  if (browser_)
    browser_->tab_strip_model()->AddObserver(this);
}

}  // namespace chromeos
