// 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_line_reader.h"

#include <algorithm>
#include <string>
#include <utility>

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"

#include "croslog/file_map_reader.h"

namespace croslog {

namespace {
// Maximum length of line in bytes.
static int64_t g_max_line_length = 1024 * 1024;
}  // namespace

// static
void LogLineReader::SetMaxLineLengthForTest(int64_t max_line_length) {
  CHECK_LE(max_line_length, FileMapReader::GetChunkSizeInBytes());
  CHECK_GE(max_line_length, 0);
  g_max_line_length = max_line_length;
}

LogLineReader::LogLineReader(Backend backend_mode)
    : backend_mode_(backend_mode) {
  // Checks the assumption of this logic.
  DCHECK_GE(FileMapReader::GetChunkSizeInBytes(), g_max_line_length);
}

LogLineReader::~LogLineReader() {
  if (file_change_watcher_)
    file_change_watcher_->RemoveWatch(file_path_);
}

void LogLineReader::OpenFile(const base::FilePath& file_path) {
  CHECK(backend_mode_ == Backend::FILE ||
        backend_mode_ == Backend::FILE_FOLLOW);

  // Ensure the values are not initialized.
  CHECK(file_path_.empty());

  file_ = base::File(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!file_.IsValid()) {
    LOG(ERROR) << "Could not open " << file_path;
    return;
  }
  file_path_ = file_path;
  pos_ = 0;

  // TODO(yoshiki): Use stat_wrapper_t and File::FStat after libchrome uprev.
  struct stat file_stat;
  if (fstat(file_.GetPlatformFile(), &file_stat) == 0)
    file_inode_ = file_stat.st_ino;
  DCHECK_NE(0, file_inode_);

  if (backend_mode_ == Backend::FILE_FOLLOW) {
    // Race may happen when the file rotates just after file opens.
    // TODO(yoshiki): detect the race. Maybe we can use /proc/self/fd/$fd.
    file_change_watcher_ = FileChangeWatcher::GetInstance();
    bool ret = file_change_watcher_->AddWatch(file_path_, this);
    if (!ret) {
      LOG(ERROR) << "Failed to install FileChangeWatcher for " << file_path_
                 << ".";
      file_change_watcher_ = nullptr;
    }
  }

  reader_ = FileMapReader::CreateReader(file_.Duplicate());
}

void LogLineReader::OpenMemoryBufferForTest(const char* buffer, size_t size) {
  CHECK(backend_mode_ == Backend::MEMORY_FOR_TEST);
  reader_ = FileMapReader::CreateFileMapReaderDelegateImplMemoryReaderForTest(
      (const uint8_t*)buffer, size);
}

void LogLineReader::SetPositionLast() {
  // At first, sets the position to EOF.
  pos_ = reader_->GetFileSize();
  DCHECK_LE(0, pos_);

  // Calculates the maximum traversable range in the file and allocate a buffer.
  int64_t pos_traversal_start = std::max(pos_ - g_max_line_length, INT64_C(0));
  int64_t traversal_length = std::min(g_max_line_length, pos_);

  // Allocates a buffer of the segment from |pos_traversal_start| to EOF.
  auto buffer = reader_->MapBuffer(pos_traversal_start, traversal_length);
  CHECK(buffer->valid()) << "Mmap failed. Maybe the file has been truncated.";

  // Traverses in reverse order to find the last LF.
  while (pos_ > pos_traversal_start && buffer->GetChar(pos_ - 1) != '\n')
    pos_--;

  if (pos_ != 0 && pos_ <= pos_traversal_start) {
    LOG(ERROR) << "The last line is too long to handle (more than: "
               << g_max_line_length
               << "bytes). Lines around here may be broken.";
    // Sets the position to the last as a sloppy solution.
    pos_ = reader_->GetFileSize();
  }
}

// Ensure the file path is initialized.
void LogLineReader::ReloadRotatedFile() {
  CHECK(backend_mode_ == Backend::FILE_FOLLOW);

  DCHECK(rotated_);
  DCHECK(PathExists(file_path_));

  rotated_ = false;

  CHECK(file_change_watcher_);
  file_change_watcher_->RemoveWatch(file_path_);

  base::FilePath file_path = file_path_;
  file_path_.clear();
  reader_.reset();
  file_inode_ = 0;
  pos_ = 0;

  OpenFile(file_path);
  if (!file_.IsValid()) {
    LOG(FATAL) << "File looks rotated, but new file can't be opened.";
  }
  reader_ = FileMapReader::CreateReader(file_.Duplicate());
}

base::Optional<std::string> LogLineReader::Forward() {
  DCHECK_LE(0, pos_);

  // Checks the current position is at the beginning of the line.
  if (pos_ != 0) {
    auto buffer = reader_->MapBuffer(pos_ - 1, 1);
    CHECK(buffer->valid()) << "Mmap failed. Maybe the file has been truncated"
                           << " and the current read position got invalid.";

    if (buffer->GetChar(pos_ - 1) != '\n') {
      LOG(WARNING) << "The line is odd. The line is too long or the file is"
                   << " unexpectedly changed.";
    }
  }

  // Calculate the maximum traversable size to allocate.
  int64_t traversal_length =
      std::min(g_max_line_length, reader_->GetFileSize() - pos_);
  int64_t pos_traversal_end = pos_ + traversal_length;

  // Allocates a buffer of the segment from |pos_| to |pos_traversal_end|.
  auto buffer = reader_->MapBuffer(pos_, traversal_length);
  CHECK(buffer->valid()) << "Mmap failed. Maybe the file has been truncated"
                         << " and the current read position got invalid.";

  // Finds the next LF (end of line).
  int64_t pos_line_end = pos_;

  while (pos_line_end < pos_traversal_end &&
         buffer->GetChar(pos_line_end) != '\n') {
    pos_line_end++;
  }

  if (pos_line_end == reader_->GetFileSize()) {
    // Reaches EOF without '\n'.
    int64_t unread_length = reader_->GetFileSize() - pos_;

    if (rotated_ && unread_length == 0 && PathExists(file_path_)) {
      // Free the mapped buffer so that another buffer map is allowed.
      buffer.reset();

      ReloadRotatedFile();
      return Forward();
    }

    // If next file doesn't exist, leave the remaining string.
    // If next file exists, read the remaining string.
    if (!rotated_)
      return base::nullopt;

    pos_line_end = reader_->GetFileSize();
  } else if (pos_line_end == (pos_ + g_max_line_length)) {
    LOG(ERROR) << "A line is too long to handle (more than "
               << g_max_line_length
               << "bytes). Lines around here may be broken.";
  }

  // Updates the current position.
  int64_t pos_line_start = pos_;
  int64_t line_length = pos_line_end - pos_;
  pos_ = pos_line_end;

  if (pos_ < reader_->GetFileSize()) {
    // Unless the line is too long, proceed the LF.
    if (buffer->GetChar(pos_) == '\n')
      pos_ += 1;
  }

  return GetString(std::move(buffer), pos_line_start, line_length);
}

base::Optional<std::string> LogLineReader::Backward() {
  DCHECK_LE(0, pos_);
  if (pos_ == 0)
    return base::nullopt;

  // Calculates the maximum traversable range in the file and allocate a buffer.
  int64_t pos_traversal_start = std::max(pos_ - g_max_line_length, INT64_C(0));
  int64_t traversal_length = pos_ - pos_traversal_start;
  DCHECK_GE(traversal_length, 0);

  // Allocates a buffer of the segment from |pos_traversal_start| to |pos_|.
  auto buffer = reader_->MapBuffer(pos_traversal_start, traversal_length);
  CHECK(buffer->valid()) << "Mmap failed. Maybe the file has been truncated"
                         << " and the current read position got invalid.";

  // Ensures the current position is the beginning of the previous line.
  if (buffer->GetChar(pos_ - 1) != '\n') {
    LOG(WARNING) << "The line is too long or the file is unexpectedly changed."
                 << " The lines read may be broken.";
  }

  // Finds the next LF (at the beginning of the line).
  int64_t last_start = pos_ - 1;
  while (last_start > pos_traversal_start &&
         buffer->GetChar(last_start - 1) != '\n') {
    last_start--;
  }

  // Ensures the next LF is found.
  if (last_start != 0 && last_start <= pos_traversal_start) {
    LOG(ERROR) << "A line is too long to handle (more than "
               << g_max_line_length
               << "bytes). Lines around here may be broken.";
  }

  // Updates the current position.
  int64_t line_length = pos_ - last_start - 1;
  pos_ = last_start;

  return GetString(std::move(buffer), last_start, line_length);
}

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

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

std::string LogLineReader::GetString(
    std::unique_ptr<FileMapReader::MappedBuffer> mapped_buffer,
    uint64_t offset,
    uint64_t length) const {
  std::pair<const uint8_t*, size_t> buffer =
      mapped_buffer->GetBuffer(offset, length);

  return std::string(reinterpret_cast<const char*>(buffer.first),
                     buffer.second);
}

void LogLineReader::OnFileContentMaybeChanged() {
  CHECK(backend_mode_ == Backend::FILE_FOLLOW);
  CHECK(file_.IsValid());

  // We didn't consider the case of content change without size change. It
  // shouldn't happen with normal log files.

  // Previous file size at (or shortly before) the previous mmap.
  const int64_t previous_file_size = reader_->GetFileSize();
  // Current file size read from the file system.
  const int64_t current_file_size = file_.GetLength();

  if (previous_file_size != current_file_size) {
    reader_->ApplyFileSizeExpansion();
    for (Observer& obs : observers_)
      obs.OnFileChanged(this);
  }
}

void LogLineReader::OnFileNameMaybeChanged() {
  CHECK(backend_mode_ == Backend::FILE_FOLLOW);

  if (rotated_)
    return;

  if (!PathExists(file_path_)) {
    rotated_ = true;
  } else {
    // TODO(yoshiki): Use stat_wrapper_t and File::Stat after libchrome uprev.
    struct stat file_stat;
    bool inode_changed = ((stat(file_path_.value().c_str(), &file_stat) == 0) &&
                          (file_inode_ != file_stat.st_ino));

    if (inode_changed)
      rotated_ = true;
  }

  if (rotated_) {
    for (Observer& obs : observers_)
      obs.OnFileChanged(this);
  }
}

}  // namespace croslog
