// Copyright 2017 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 "components/metrics/metrics_log_store.h"

#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/persisted_logs_metrics_impl.h"
#include "components/prefs/pref_registry_simple.h"

namespace metrics {

namespace {

// The number of "initial" logs to save, and hope to send during a future Chrome
// session.  Initial logs contain crash stats, and are pretty small.
const size_t kInitialLogsPersistLimit = 20;

// The number of ongoing logs to save persistently, and hope to
// send during a this or future sessions.  Note that each log may be pretty
// large, as presumably the related "initial" log wasn't sent (probably nothing
// was, as the user was probably off-line).  As a result, the log probably kept
// accumulating while the "initial" log was stalled, and couldn't be sent.  As a
// result, we don't want to save too many of these mega-logs.
// A "standard shutdown" will create a small log, including just the data that
// was not yet been transmitted, and that is normal (to have exactly one
// ongoing_log_ at startup).
const size_t kOngoingLogsPersistLimit = 8;

// The number of bytes of logs to save of each type (initial/ongoing).
// This ensures that a reasonable amount of history will be stored even if there
// is a long series of very small logs.
const size_t kStorageByteLimitPerLogType = 300 * 1000;  // ~300kB

}  // namespace

// static
void MetricsLogStore::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterListPref(prefs::kMetricsInitialLogs);
  registry->RegisterListPref(prefs::kMetricsOngoingLogs);
}

MetricsLogStore::MetricsLogStore(PrefService* local_state,
                                 size_t max_ongoing_log_size)
    : unsent_logs_loaded_(false),
      initial_log_queue_(std::unique_ptr<PersistedLogsMetricsImpl>(
                             new PersistedLogsMetricsImpl()),
                         local_state,
                         prefs::kMetricsInitialLogs,
                         kInitialLogsPersistLimit,
                         kStorageByteLimitPerLogType,
                         0),
      ongoing_log_queue_(std::unique_ptr<PersistedLogsMetricsImpl>(
                             new PersistedLogsMetricsImpl()),
                         local_state,
                         prefs::kMetricsOngoingLogs,
                         kOngoingLogsPersistLimit,
                         kStorageByteLimitPerLogType,
                         max_ongoing_log_size) {}

MetricsLogStore::~MetricsLogStore() {}

void MetricsLogStore::LoadPersistedUnsentLogs() {
  initial_log_queue_.LoadPersistedUnsentLogs();
  ongoing_log_queue_.LoadPersistedUnsentLogs();
  unsent_logs_loaded_ = true;
}

void MetricsLogStore::StoreLog(const std::string& log_data,
                               MetricsLog::LogType log_type) {
  switch (log_type) {
    case MetricsLog::INITIAL_STABILITY_LOG:
      initial_log_queue_.StoreLog(log_data);
      break;
    case MetricsLog::ONGOING_LOG:
    case MetricsLog::INDEPENDENT_LOG:
      ongoing_log_queue_.StoreLog(log_data);
      break;
  }
}

bool MetricsLogStore::has_unsent_logs() const {
  return initial_log_queue_.has_unsent_logs() ||
         ongoing_log_queue_.has_unsent_logs();
}

bool MetricsLogStore::has_staged_log() const {
  return initial_log_queue_.has_staged_log() ||
         ongoing_log_queue_.has_staged_log();
}

const std::string& MetricsLogStore::staged_log() const {
  return initial_log_queue_.has_staged_log() ? initial_log_queue_.staged_log()
                                             : ongoing_log_queue_.staged_log();
}

const std::string& MetricsLogStore::staged_log_hash() const {
  return initial_log_queue_.has_staged_log()
             ? initial_log_queue_.staged_log_hash()
             : ongoing_log_queue_.staged_log_hash();
}

void MetricsLogStore::StageNextLog() {
  DCHECK(!has_staged_log());
  if (initial_log_queue_.has_unsent_logs())
    initial_log_queue_.StageNextLog();
  else
    ongoing_log_queue_.StageNextLog();
}

void MetricsLogStore::DiscardStagedLog() {
  DCHECK(has_staged_log());
  if (initial_log_queue_.has_staged_log())
    initial_log_queue_.DiscardStagedLog();
  else
    ongoing_log_queue_.DiscardStagedLog();
  DCHECK(!has_staged_log());
}

void MetricsLogStore::PersistUnsentLogs() const {
  DCHECK(unsent_logs_loaded_);
  if (!unsent_logs_loaded_)
    return;

  initial_log_queue_.PersistUnsentLogs();
  ongoing_log_queue_.PersistUnsentLogs();
}

}  // namespace metrics
