// Copyright 2020 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/log_entry_reader.h"

#include <list>
#include <utility>

#include "base/optional.h"
#include "base/strings/string_util.h"

#include "croslog/log_parser_syslog.h"

namespace croslog {

LogEntryReader::LogEntryReader(base::FilePath log_file,
                               std::unique_ptr<LogParser> parser_in,
                               bool install_change_watcher)
    : file_path_(log_file),
      line_reader_(install_change_watcher ? LogLineReader::Backend::FILE_FOLLOW
                                          : LogLineReader::Backend::FILE),
      parser_(std::move(parser_in)) {
  line_reader_.OpenFile(std::move(log_file));
}

MaybeLogEntry LogEntryReader::GetPreviousEntry() {
  // If we have looked ahead, go back to the current position and invalidate the
  // cache.
  if (next_entry_.has_value()) {
    line_reader_.Backward();
    next_entry_.reset();
  }

  std::list<std::string> lines;
  // Reads preceding lines until a parsable line, which should be the first
  // line of log entry, comes.
  while (true) {
    auto [line, result] = line_reader_.Backward();
    if (result != LogLineReader::ReadResult::NO_ERROR) {
      // No more entry or failed to read
      return base::nullopt;
    }

    MaybeLogEntry entry = parser_->Parse(std::move(line));
    if (entry.has_value()) {
      if (!lines.empty())
        entry->AppendLinesToMessage(lines);
      return entry;
    }

    lines.push_front(std::move(line));
  }
}

MaybeLogEntry LogEntryReader::GetNextEntry() {
  MaybeLogEntry entry;
  if (!next_entry_.has_value()) {
    // Reads a next lines with skipping non-parsable lines.
    while (true) {
      auto [line, result] = line_reader_.Forward();
      if (result != LogLineReader::ReadResult::NO_ERROR) {
        // No more entry or failed to read
        return base::nullopt;
      }

      MaybeLogEntry maybe_entry = parser_->Parse(std::move(line));
      if (!maybe_entry.has_value()) {
        // Parse failed. Go to the next line.
        continue;
      }

      entry.emplace(std::move(*maybe_entry));
      break;
    }
  } else {
    entry.emplace(std::move(*next_entry_));
    next_entry_.reset();
  }

  std::list<std::string> lines;
  // Reads succeeding lines until a parsable line, which should be the first
  // line of the next log entry, comes.
  while (true) {
    auto [line, result] = line_reader_.Forward();
    if (result != LogLineReader::ReadResult::NO_ERROR) {
      // No more entry
      break;
    }

    MaybeLogEntry maybe_entry = parser_->Parse(std::move(line));
    if (maybe_entry.has_value()) {
      next_entry_.emplace(std::move(*maybe_entry));
      break;
    }

    lines.push_back(std::move(line));
  }

  entry->AppendLinesToMessage(lines);
  return entry;
}

void LogEntryReader::SetPositionLast() {
  line_reader_.SetPositionLast();
}

void LogEntryReader::AddObserver(LogLineReader::Observer* obs) {
  line_reader_.AddObserver(obs);
}

void LogEntryReader::RemoveObserver(LogLineReader::Observer* obs) {
  line_reader_.RemoveObserver(obs);
}

}  // namespace croslog
