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

#include <algorithm>
#include <string>
#include <vector>

#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>

#include "croslog/constants.h"

namespace log_rotator {

constexpr int DAYS_TO_PRESERVE_LOGS = 7;

LogRotator::LogRotator(base::FilePath base_log_path)
    : base_log_path_(base_log_path) {}

// Creating a new log file for Forwarder is handled outside this code.

base::FilePath LogRotator::GetFilePathWithIndex(int index) {
  CHECK_GE(index, 0);
  if (index == 0)
    return base_log_path_;

  return base_log_path_.InsertBeforeExtensionASCII("." +
                                                   base::NumberToString(index));
}

int LogRotator::GetIndexFromFilePath(const base::FilePath& log_path) {
  if (log_path == base_log_path_)
    return 0;

  if (log_path.value().length() <= base_log_path_.value().length()) {
    // Invalid input, since the given path must be longer than the base path.
    return -1;
  }

  // Verify the base part (before the index number) of the path.
  const base::FilePath base_path_body = base_log_path_.RemoveFinalExtension();
  size_t base_path_body_len = base_path_body.value().length();
  const std::string& log_path_body =
      log_path.value().substr(0, base_path_body_len);
  if (log_path_body != base_path_body.value()) {
    // Invalid input, since the path str doesn't start with the path string
    return -1;
  }
  if (log_path.value()[base_path_body_len] != '.') {
    // Invalid input, since in the path, the dot doesn't follow with the base
    // path.
    return -1;
  }

  // Verify the final extension of the path.
  const std::string& final_extension = base_log_path_.FinalExtension();
  size_t final_extension_len = final_extension.length();
  const std::string& log_path_final_extension = log_path.value().substr(
      log_path.value().length() - final_extension_len, final_extension_len);
  if (log_path_final_extension != final_extension) {
    // Invalid input, since the path str doesn't start with the path string
    return -1;
  }

  // Extract the index number.
  const std::string& log_path_index_str = log_path.value().substr(
      base_path_body_len + 1,
      log_path.value().length() - base_path_body_len - final_extension_len - 1);
  int index = 0;
  if (!base::StringToInt(log_path_index_str, &index))
    return -1;

  if (index == 0) {
    // The ".0" extension is invalid. The 0-th file should have no extension.
    return -1;
  }

  return index;
}

void LogRotator::CleanUpFiles(int max_index) {
  base::FilePath dir = base_log_path_.DirName();
  base::FilePath pattern = base_log_path_.BaseName().AddExtension("*");

  base::FileEnumerator file_enumerator(dir, false, base::FileEnumerator::FILES,
                                       pattern.value());

  while (!file_enumerator.Next().empty()) {
    base::FilePath file_path = dir.Append(file_enumerator.GetInfo().GetName());
    int index = GetIndexFromFilePath(file_path);
    if (index > max_index || index < 0)
      base::DeleteFile(file_path);
  }
}

void LogRotator::RotateLogFile(int max_index) {
  std::vector<base::FileEnumerator::FileInfo> info;

  base::FilePath max_index_path = GetFilePathWithIndex(max_index);
  if (base::PathExists(max_index_path))
    base::DeleteFile(max_index_path);

  for (int i = (max_index - 1); i >= 0; --i) {
    base::FilePath old_path = GetFilePathWithIndex(i);
    base::FilePath new_path = GetFilePathWithIndex(i + 1);

    if (!base::PathExists(old_path))
      continue;

    if (!base::Move(old_path, new_path)) {
      LOG(ERROR) << "File error while moving " << old_path << " to " << new_path
                 << ": "
                 << base::File::ErrorToString(base::File::GetLastFileError());
    }
  }

  CleanUpFiles(max_index);
}

void RotateStandardLogFiles() {
  for (const auto& base_log_path_str : croslog::kLogsToRotate) {
    const base::FilePath& base_log_path =
        base::FilePath{base_log_path_str.data()};
    LogRotator rotator(base_log_path);
    rotator.RotateLogFile(DAYS_TO_PRESERVE_LOGS);
  }
}

}  // namespace log_rotator
