// 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 "crash-reporter/anomaly_detector_text_file_reader.h"

#include <stdio.h>

#include <cerrno>
#include <string>
#include <vector>

#include <sys/stat.h>

namespace anomaly {

TextFileReader::TextFileReader(const base::FilePath& path)
    : file_path_(path), buf_(kBufferSize_) {
  Open();
}

TextFileReader::~TextFileReader() {}

bool TextFileReader::GetLine(std::string* line) {
  if (!file_.IsValid() && !Open())
    return false;

  bool end_of_file = false;
  while (!end_of_file) {
    for (; pos_ < end_pos_; pos_++) {
      if (buf_[pos_] == '\n') {
        if (skip_next_) {
          skip_next_ = false;
          line_fragment_.clear();
          continue;
        }

        pos_++;
        *line = std::string(line_fragment_.begin(), line_fragment_.end());
        line_fragment_.clear();
        return true;
      }

      line_fragment_.push_back(buf_[pos_]);
    }

    end_of_file = true;
    if (LoadToBuffer()) {
      end_of_file = false;
    }
  }

  return false;
}

bool TextFileReader::Open() {
  if (kMaxOpenRetries_ == open_tries_) {
    // Simply return false if the number of retries have reached the limit.
    return false;
  }
  open_tries_++;

  file_ = base::File(file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ);

  if (!file_.IsValid()) {
    PLOG(WARNING) << "Try #" << open_tries_
                  << " Failed to open file: " << file_path_.value();

    if (kMaxOpenRetries_ == open_tries_) {
      LOG(ERROR) << "Max number of retries to open file " << file_path_.value()
                 << " reached.";
    }
    return false;
  }

  // Reset open_tries_ upon successful Open().
  open_tries_ = 0;

  struct stat st;
  // Use fstat instead of stat to make sure that it gets the inode number for
  // the file that was opened.
  CHECK_GE(fstat(file_.GetPlatformFile(), &st), 0);
  inode_number_ = st.st_ino;
  Clear();
  return true;
}

bool TextFileReader::LoadToBuffer() {
  pos_ = 0;
  end_pos_ = 0;

  int64_t bytes_read = file_.ReadAtCurrentPos(buf_.data(), buf_.size());
  if (bytes_read > 0) {
    end_pos_ = bytes_read;
    return true;
  }

  // In the unlikely event that Open() fails after CheckForNewFile()
  // returned true, TextFileReader will try to open the file again every time
  // GetLine is called before max number of retries is reached.
  if (CheckForNewFile() && Open()) {
    // rsyslog ensures that a line does not get split between restarts (e.g.
    // during log rotation by chromeos-cleanup-logs) meaning the logs at the end
    // of the original file will be a complete line. Therefore we can safely
    // assume that line_fragment_ is empty and thus can be cleared.
    return LoadToBuffer();
  }

  return false;
}

bool TextFileReader::CheckForNewFile() {
  struct stat st;

  int result = stat(file_path_.value().c_str(), &st);

  // This can happen if a the file_ has been moved but a new file at file_path
  // has not been created yet.
  if (result < 0)
    return false;

  return inode_number_ != st.st_ino;
}

void TextFileReader::SeekToEnd() {
  if (!file_.IsValid())
    return;

  skip_next_ = true;
  Clear();
  file_.Seek(base::File::FROM_END, -1);
}

void TextFileReader::SeekToBegin() {
  if (!file_.IsValid())
    return;

  skip_next_ = false;
  Clear();
  file_.Seek(base::File::FROM_BEGIN, 0);
}

void TextFileReader::Clear() {
  line_fragment_.clear();
  end_pos_ = 0;
  pos_ = 0;
}

}  // namespace anomaly
