/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/filerotatingstream.h"

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

#if defined(WEBRTC_WIN)
#include <windows.h>
#include "rtc_base/stringutils.h"
#else
#include <dirent.h>
#include <sys/stat.h>
#endif  // WEBRTC_WIN

#include "absl/strings/match.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

// Note: We use fprintf for logging in the write paths of this stream to avoid
// infinite loops when logging.

namespace rtc {

namespace {

std::string AddTrailingPathDelimiterIfNeeded(std::string directory);

// |dir| must have a trailing delimiter. |prefix| must not include wild card
// characters.
std::vector<std::string> GetFilesWithPrefix(const std::string& directory,
                                            const std::string& prefix);
bool DeleteFile(const std::string& file);
bool MoveFile(const std::string& old_file, const std::string& new_file);
bool IsFile(const std::string& file);
bool IsFolder(const std::string& file);
absl::optional<size_t> GetFileSize(const std::string& file);

#if defined(WEBRTC_WIN)

std::string AddTrailingPathDelimiterIfNeeded(std::string directory) {
  if (absl::EndsWith(directory, "\\")) {
    return directory;
  }
  return directory + "\\";
}

std::vector<std::string> GetFilesWithPrefix(const std::string& directory,
                                            const std::string& prefix) {
  RTC_DCHECK(absl::EndsWith(directory, "\\"));
  WIN32_FIND_DATA data;
  HANDLE handle;
  handle = ::FindFirstFile(ToUtf16(directory + prefix + '*').c_str(), &data);
  if (handle == INVALID_HANDLE_VALUE)
    return {};

  std::vector<std::string> file_list;
  do {
    file_list.emplace_back(directory + ToUtf8(data.cFileName));
  } while (::FindNextFile(handle, &data) == TRUE);

  ::FindClose(handle);
  return file_list;
}

bool DeleteFile(const std::string& file) {
  return ::DeleteFile(ToUtf16(file).c_str()) != 0;
}

bool MoveFile(const std::string& old_file, const std::string& new_file) {
  return ::MoveFile(ToUtf16(old_file).c_str(), ToUtf16(new_file).c_str()) != 0;
}

bool IsFile(const std::string& file) {
  WIN32_FILE_ATTRIBUTE_DATA data = {0};
  if (0 == ::GetFileAttributesEx(ToUtf16(file).c_str(), GetFileExInfoStandard,
                                 &data))
    return false;
  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
}

bool IsFolder(const std::string& file) {
  WIN32_FILE_ATTRIBUTE_DATA data = {0};
  if (0 == ::GetFileAttributesEx(ToUtf16(file).c_str(), GetFileExInfoStandard,
                                 &data))
    return false;
  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
         FILE_ATTRIBUTE_DIRECTORY;
}

absl::optional<size_t> GetFileSize(const std::string& file) {
  WIN32_FILE_ATTRIBUTE_DATA data = {0};
  if (::GetFileAttributesEx(ToUtf16(file).c_str(), GetFileExInfoStandard,
                            &data) == 0)
    return absl::nullopt;
  return data.nFileSizeLow;
}

#else  // defined(WEBRTC_WIN)

std::string AddTrailingPathDelimiterIfNeeded(std::string directory) {
  if (absl::EndsWith(directory, "/")) {
    return directory;
  }
  return directory + "/";
}

std::vector<std::string> GetFilesWithPrefix(const std::string& directory,
                                            const std::string& prefix) {
  RTC_DCHECK(absl::EndsWith(directory, "/"));
  DIR* dir = ::opendir(directory.c_str());
  if (dir == nullptr)
    return {};
  std::vector<std::string> file_list;
  for (struct dirent* dirent = ::readdir(dir); dirent;
       dirent = ::readdir(dir)) {
    std::string name = dirent->d_name;
    if (name.compare(0, prefix.size(), prefix) == 0) {
      file_list.emplace_back(directory + name);
    }
  }
  ::closedir(dir);
  return file_list;
}

bool DeleteFile(const std::string& file) {
  return ::unlink(file.c_str()) == 0;
}

bool MoveFile(const std::string& old_file, const std::string& new_file) {
  return ::rename(old_file.c_str(), new_file.c_str()) == 0;
}

bool IsFile(const std::string& file) {
  struct stat st;
  int res = ::stat(file.c_str(), &st);
  // Treat symlinks, named pipes, etc. all as files.
  return res == 0 && !S_ISDIR(st.st_mode);
}

bool IsFolder(const std::string& file) {
  struct stat st;
  int res = ::stat(file.c_str(), &st);
  return res == 0 && S_ISDIR(st.st_mode);
}

absl::optional<size_t> GetFileSize(const std::string& file) {
  struct stat st;
  if (::stat(file.c_str(), &st) != 0)
    return absl::nullopt;
  return st.st_size;
}

#endif

}  // namespace

FileRotatingStream::FileRotatingStream(const std::string& dir_path,
                                       const std::string& file_prefix)
    : FileRotatingStream(dir_path, file_prefix, 0, 0, kRead) {}

FileRotatingStream::FileRotatingStream(const std::string& dir_path,
                                       const std::string& file_prefix,
                                       size_t max_file_size,
                                       size_t num_files)
    : FileRotatingStream(dir_path,
                         file_prefix,
                         max_file_size,
                         num_files,
                         kWrite) {
  RTC_DCHECK_GT(max_file_size, 0);
  RTC_DCHECK_GT(num_files, 1);
}

FileRotatingStream::FileRotatingStream(const std::string& dir_path,
                                       const std::string& file_prefix,
                                       size_t max_file_size,
                                       size_t num_files,
                                       Mode mode)
    : dir_path_(AddTrailingPathDelimiterIfNeeded(dir_path)),
      file_prefix_(file_prefix),
      mode_(mode),
      file_stream_(nullptr),
      max_file_size_(max_file_size),
      current_file_index_(0),
      rotation_index_(0),
      current_bytes_written_(0),
      disable_buffering_(false) {
  RTC_DCHECK(IsFolder(dir_path));
  switch (mode) {
    case kWrite: {
      file_names_.clear();
      for (size_t i = 0; i < num_files; ++i) {
        file_names_.push_back(GetFilePath(i, num_files));
      }
      rotation_index_ = num_files - 1;
      break;
    }
    case kRead: {
      file_names_ = GetFilesWithPrefix(dir_path_, file_prefix_);
      std::sort(file_names_.begin(), file_names_.end());
      if (file_names_.size() > 0) {
        // |file_names_| is sorted newest first, so read from the end.
        current_file_index_ = file_names_.size() - 1;
      }
      break;
    }
  }
}

FileRotatingStream::~FileRotatingStream() {}

StreamState FileRotatingStream::GetState() const {
  if (mode_ == kRead && current_file_index_ < file_names_.size()) {
    return SS_OPEN;
  }
  if (!file_stream_) {
    return SS_CLOSED;
  }
  return file_stream_->GetState();
}

StreamResult FileRotatingStream::Read(void* buffer,
                                      size_t buffer_len,
                                      size_t* read,
                                      int* error) {
  RTC_DCHECK(buffer);
  if (mode_ != kRead) {
    return SR_EOS;
  }
  if (current_file_index_ >= file_names_.size()) {
    return SR_EOS;
  }
  // We will have no file stream initially, and when we are finished with the
  // previous file.
  if (!file_stream_) {
    if (!OpenCurrentFile()) {
      return SR_ERROR;
    }
  }
  int local_error = 0;
  if (!error) {
    error = &local_error;
  }
  StreamResult result = file_stream_->Read(buffer, buffer_len, read, error);
  if (result == SR_EOS || result == SR_ERROR) {
    if (result == SR_ERROR) {
      RTC_LOG(LS_ERROR) << "Failed to read from: "
                        << file_names_[current_file_index_]
                        << "Error: " << error;
    }
    // Reached the end of the file, read next file. If there is an error return
    // the error status but allow for a next read by reading next file.
    CloseCurrentFile();
    if (current_file_index_ == 0) {
      // Just finished reading the last file, signal EOS by setting index.
      current_file_index_ = file_names_.size();
    } else {
      --current_file_index_;
    }
    if (read) {
      *read = 0;
    }
    return result == SR_EOS ? SR_SUCCESS : result;
  } else if (result == SR_SUCCESS) {
    // Succeeded, continue reading from this file.
    return SR_SUCCESS;
  } else {
    RTC_NOTREACHED();
  }
  return result;
}

StreamResult FileRotatingStream::Write(const void* data,
                                       size_t data_len,
                                       size_t* written,
                                       int* error) {
  if (mode_ != kWrite) {
    return SR_EOS;
  }
  if (!file_stream_) {
    std::fprintf(stderr, "Open() must be called before Write.\n");
    return SR_ERROR;
  }
  // Write as much as will fit in to the current file.
  RTC_DCHECK_LT(current_bytes_written_, max_file_size_);
  size_t remaining_bytes = max_file_size_ - current_bytes_written_;
  size_t write_length = std::min(data_len, remaining_bytes);
  size_t local_written = 0;
  if (!written) {
    written = &local_written;
  }
  StreamResult result = file_stream_->Write(data, write_length, written, error);
  current_bytes_written_ += *written;

  // If we're done with this file, rotate it out.
  if (current_bytes_written_ >= max_file_size_) {
    RTC_DCHECK_EQ(current_bytes_written_, max_file_size_);
    RotateFiles();
  }
  return result;
}

bool FileRotatingStream::Flush() {
  if (!file_stream_) {
    return false;
  }
  return file_stream_->Flush();
}

bool FileRotatingStream::GetSize(size_t* size) const {
  if (mode_ != kRead) {
    // Not possible to get accurate size on disk when writing because of
    // potential buffering.
    return false;
  }
  RTC_DCHECK(size);
  *size = 0;
  size_t total_size = 0;
  for (auto file_name : file_names_) {
    total_size += GetFileSize(file_name).value_or(0);
  }
  *size = total_size;
  return true;
}

void FileRotatingStream::Close() {
  CloseCurrentFile();
}

bool FileRotatingStream::Open() {
  switch (mode_) {
    case kRead:
      // Defer opening to when we first read since we want to return read error
      // if we fail to open next file.
      return true;
    case kWrite: {
      // Delete existing files when opening for write.
      std::vector<std::string> matching_files =
          GetFilesWithPrefix(dir_path_, file_prefix_);
      for (const auto& matching_file : matching_files) {
        if (!DeleteFile(matching_file)) {
          std::fprintf(stderr, "Failed to delete: %s\n", matching_file.c_str());
        }
      }
      return OpenCurrentFile();
    }
  }
  return false;
}

bool FileRotatingStream::DisableBuffering() {
  disable_buffering_ = true;
  if (!file_stream_) {
    std::fprintf(stderr, "Open() must be called before DisableBuffering().\n");
    return false;
  }
  return file_stream_->DisableBuffering();
}

std::string FileRotatingStream::GetFilePath(size_t index) const {
  RTC_DCHECK_LT(index, file_names_.size());
  return file_names_[index];
}

bool FileRotatingStream::OpenCurrentFile() {
  CloseCurrentFile();

  // Opens the appropriate file in the appropriate mode.
  RTC_DCHECK_LT(current_file_index_, file_names_.size());
  std::string file_path = file_names_[current_file_index_];
  file_stream_.reset(new FileStream());
  const char* mode = nullptr;
  switch (mode_) {
    case kWrite:
      mode = "w+";
      // We should always we writing to the zero-th file.
      RTC_DCHECK_EQ(current_file_index_, 0);
      break;
    case kRead:
      mode = "r";
      break;
  }
  int error = 0;
  if (!file_stream_->Open(file_path, mode, &error)) {
    std::fprintf(stderr, "Failed to open: %s Error: %i\n", file_path.c_str(),
                 error);
    file_stream_.reset();
    return false;
  }
  if (disable_buffering_) {
    file_stream_->DisableBuffering();
  }
  return true;
}

void FileRotatingStream::CloseCurrentFile() {
  if (!file_stream_) {
    return;
  }
  current_bytes_written_ = 0;
  file_stream_.reset();
}

void FileRotatingStream::RotateFiles() {
  RTC_DCHECK_EQ(mode_, kWrite);
  CloseCurrentFile();
  // Rotates the files by deleting the file at |rotation_index_|, which is the
  // oldest file and then renaming the newer files to have an incremented index.
  // See header file comments for example.
  RTC_DCHECK_LT(rotation_index_, file_names_.size());
  std::string file_to_delete = file_names_[rotation_index_];
  if (IsFile(file_to_delete)) {
    if (!DeleteFile(file_to_delete)) {
      std::fprintf(stderr, "Failed to delete: %s\n", file_to_delete.c_str());
    }
  }
  for (auto i = rotation_index_; i > 0; --i) {
    std::string rotated_name = file_names_[i];
    std::string unrotated_name = file_names_[i - 1];
    if (IsFile(unrotated_name)) {
      if (!MoveFile(unrotated_name, rotated_name)) {
        std::fprintf(stderr, "Failed to move: %s to %s\n",
                     unrotated_name.c_str(), rotated_name.c_str());
      }
    }
  }
  // Create a new file for 0th index.
  OpenCurrentFile();
  OnRotation();
}

std::string FileRotatingStream::GetFilePath(size_t index,
                                            size_t num_files) const {
  RTC_DCHECK_LT(index, num_files);

  const size_t buffer_size = 32;
  char file_postfix[buffer_size];
  // We want to zero pad the index so that it will sort nicely.
  const int max_digits = std::snprintf(nullptr, 0, "%zu", num_files - 1);
  RTC_DCHECK_LT(1 + max_digits, buffer_size);
  std::snprintf(file_postfix, buffer_size, "_%0*zu", max_digits, index);

  return dir_path_ + file_prefix_ + file_postfix;
}

CallSessionFileRotatingStream::CallSessionFileRotatingStream(
    const std::string& dir_path)
    : FileRotatingStream(dir_path, kLogPrefix),
      max_total_log_size_(0),
      num_rotations_(0) {}

CallSessionFileRotatingStream::CallSessionFileRotatingStream(
    const std::string& dir_path,
    size_t max_total_log_size)
    : FileRotatingStream(dir_path,
                         kLogPrefix,
                         max_total_log_size / 2,
                         GetNumRotatingLogFiles(max_total_log_size) + 1),
      max_total_log_size_(max_total_log_size),
      num_rotations_(0) {
  RTC_DCHECK_GE(max_total_log_size, 4);
}

const char* CallSessionFileRotatingStream::kLogPrefix = "webrtc_log";
const size_t CallSessionFileRotatingStream::kRotatingLogFileDefaultSize =
    1024 * 1024;

void CallSessionFileRotatingStream::OnRotation() {
  ++num_rotations_;
  if (num_rotations_ == 1) {
    // On the first rotation adjust the max file size so subsequent files after
    // the first are smaller.
    SetMaxFileSize(GetRotatingLogSize(max_total_log_size_));
  } else if (num_rotations_ == (GetNumFiles() - 1)) {
    // On the next rotation the very first file is going to be deleted. Change
    // the rotation index so this doesn't happen.
    SetRotationIndex(GetRotationIndex() - 1);
  }
}

size_t CallSessionFileRotatingStream::GetRotatingLogSize(
    size_t max_total_log_size) {
  size_t num_rotating_log_files = GetNumRotatingLogFiles(max_total_log_size);
  size_t rotating_log_size = num_rotating_log_files > 2
                                 ? kRotatingLogFileDefaultSize
                                 : max_total_log_size / 4;
  return rotating_log_size;
}

size_t CallSessionFileRotatingStream::GetNumRotatingLogFiles(
    size_t max_total_log_size) {
  // At minimum have two rotating files. Otherwise split the available log size
  // evenly across 1MB files.
  return std::max((size_t)2,
                  (max_total_log_size / 2) / kRotatingLogFileDefaultSize);
}

}  // namespace rtc
