// Copyright 2021 The Chromium OS 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 "croslog/metrics_collector_util.h"

#include <algorithm>
#include <deque>
#include <functional>
#include <string>
#include <utility>
#include <vector>

#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"

#include "croslog/log_entry_reader.h"
#include "croslog/log_parser_syslog.h"

namespace croslog {

void CalculateLogMetrics(const base::FilePath& path,
                         const base::Time& count_after,
                         std::unique_ptr<LogParser> parser_in,
                         int64_t* byte_count_out,
                         int64_t* entry_count_out,
                         int64_t* max_throughput_out) {
  // Checks if the file exists.
  if (!base::PathExists(path)) {
    if (byte_count_out)
      *byte_count_out = -1;
    if (entry_count_out)
      *entry_count_out = -1;
    if (max_throughput_out)
      *max_throughput_out = -1;
    return;
  }

  if (byte_count_out)
    *byte_count_out = 0;
  if (entry_count_out)
    *entry_count_out = 0;
  if (max_throughput_out)
    *max_throughput_out = 0;

  LogEntryReader reader(path, std::move(parser_in), false);

  // Traverses reversely from the last.
  reader.SetPositionLast();

  std::deque<base::Time> recent_timestamps;
  while (true) {
    MaybeLogEntry entry = reader.GetPreviousEntry();
    if (!entry.has_value())
      return;

    if (!count_after.is_null() && entry->time() < count_after)
      return;

    if (byte_count_out && *byte_count_out >= 0) {
      *byte_count_out += entry->entire_line().size();
      // Adding 1 for a terminating LF.
      *byte_count_out += 1;
    }

    if (max_throughput_out) {
      // Resets the state, if the timestamps are in a wrong order.
      if (!recent_timestamps.empty() &&
          recent_timestamps.back() < entry->time()) {
        recent_timestamps.clear();
      }

      // Keeps the timestamps only within 1 minute.
      recent_timestamps.push_back(entry->time());
      while ((recent_timestamps.front() - entry->time()) >
             base::TimeDelta::FromMinutes(1)) {
        recent_timestamps.pop_front();
      }

      // Get the current throughput (number of entries within the recent 1
      // minute).
      int64_t current_throughput =
          static_cast<int64_t>(recent_timestamps.size());

      *max_throughput_out = std::max(*max_throughput_out, current_throughput);
    }

    if (entry_count_out)
      (*entry_count_out)++;
  }
}

void CalculateMultipleLogMetrics(Multiplexer* multiplexer,
                                 const base::Time& count_after,
                                 int64_t* entry_count_out,
                                 int64_t* max_throughput_out) {
  multiplexer->SetLinesFromLast(0);

  if (entry_count_out)
    *entry_count_out = 0;
  if (max_throughput_out)
    *max_throughput_out = 0;

  std::deque<base::Time> recent_timestamps;
  while (true) {
    const MaybeLogEntry& entry = multiplexer->Backward();
    if (!entry.has_value())
      return;

    if (!count_after.is_null() && entry->time() < count_after)
      return;

    if (max_throughput_out) {
      // Resets the state, if the timestamp order is strange.
      if (!recent_timestamps.empty() &&
          recent_timestamps.back() < entry->time()) {
        recent_timestamps.clear();
      }

      // Keeps the timestamps only within 1 minute.
      recent_timestamps.push_back(entry->time());
      while ((recent_timestamps.front() - entry->time()) >
             base::TimeDelta::FromMinutes(1)) {
        recent_timestamps.pop_front();
      }

      // Get the current throughput (number of entries with the recent 1
      // minute).
      int64_t current_throughput =
          static_cast<int64_t>(recent_timestamps.size());

      *max_throughput_out = std::max(*max_throughput_out, current_throughput);
    }

    if (entry_count_out)
      (*entry_count_out)++;
  }
}

void CalculateChromeLogMetrics(const base::FilePath& directory,
                               const char* filename_pattern,
                               const base::Time& count_after,
                               int64_t* byte_count_out,
                               int64_t* entry_count_out,
                               int64_t* max_throughput_out) {
  // This logic traverses the chrome logs, since the chrome logs are splitted
  // on every session, instead of daily rotation like other log files.

  if (entry_count_out)
    *entry_count_out = 0;
  if (byte_count_out)
    *byte_count_out = 0;
  if (max_throughput_out)
    *max_throughput_out = 0;

  std::vector<base::FilePath> file_path;
  base::FileEnumerator e(directory, false, base::FileEnumerator::FILES,
                         filename_pattern);
  // FileEnumerator doesn't guarantee order of results, so we put the result
  // into the vector and sort it.
  for (base::FilePath name = e.Next(); !name.empty(); name = e.Next()) {
    file_path.push_back(name);
  }
  // Sorting is in reverse lexicographic order, which will also sort the logs by
  // time (more recent file first), since the chrome logs contain date and time
  // in their filenames. For example, "chrome_20210115_123456.txt" comes before
  // "chrome_20210115_123456.txt".
  std::sort(
      file_path.begin(), file_path.end(),
      [](const auto& l, const auto& r) { return r.BaseName() < l.BaseName(); });

  for (const base::FilePath& name : file_path) {
    int64_t file_size;
    if (!GetFileSize(name, &file_size) || file_size == 0)
      continue;

    int64_t byte_count_temporary;
    int64_t entry_count_temporary;
    int64_t max_throughput_temporary;
    CalculateLogMetrics(name, count_after, std::make_unique<LogParserSyslog>(),
                        &byte_count_temporary, &entry_count_temporary,
                        &max_throughput_temporary);

    // Skips this file since the file doesn't exist (this rarely happens by
    // file remove/rename race).
    if (entry_count_temporary < 0)
      continue;

    // Stops the traversal. We found no entries newer than |count_after| in
    // this log files. So, we assume the later files contain older entries,
    // since the file list has been sorted (more recent file first).
    if (entry_count_temporary == 0)
      return;

    if (entry_count_out)
      *entry_count_out += entry_count_temporary;
    if (byte_count_out)
      *byte_count_out += byte_count_temporary;
    if (max_throughput_out) {
      *max_throughput_out =
          std::max(*max_throughput_out, max_throughput_temporary);
    }
  }
}

}  // namespace croslog
