// 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 "bootid-logger/timestamp_util.h"

#include <memory>
#include <string>

#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>

#include "bootid-logger/constants.h"
#include "croslog/log_entry_reader.h"
#include "croslog/log_parser_syslog.h"

// The list is coped from /platform2/init/chromeos-cleanup-logs
// TODO(crbug.com/1168393): share the list with the rotation script.
const char* kLogFiles[] = {"messages",
                           "secure",
                           "net.log",
                           "faillog",
                           "session_manager",
                           "atrus.log",
                           "tlsdate.log",
                           "authpolicy.log",
                           "tpm-firmware-updater.log",
                           "arc.log",
                           "recover_duts/recover_duts.log",
                           "hammerd.log",
                           "upstart.log",
                           "typecd.log",
                           "bluetooth.log",
                           NULL};

base::FilePath kLogDir("/var/log");

base::Time GetFirstTimestamp(const base::FilePath& file) {
  croslog::LogEntryReader reader(
      file, std::make_unique<croslog::LogParserSyslog>(), false);
  croslog::MaybeLogEntry e = reader.GetNextEntry();
  if (e.has_value())
    return e->time();

  return base::Time();
}

base::Time GetOldestTimestampFromLogFiles(const base::FilePath& dir_path,
                                          const std::string& base_log_name) {
  base::Time oldest_last_modified;

  // Retrieve the path and the last modified date of the latest log file
  // (without a suffix).
  {
    base::FilePath log_file_path = dir_path.Append(base_log_name);
    if (base::PathExists(log_file_path))
      oldest_last_modified = GetFirstTimestamp(log_file_path);
  }

  // Pattern to match the older log files with suffix.
  std::string pattern = base_log_name + ".*";

  // Traverse the older log files.
  base::FileEnumerator e(dir_path, false, base::FileEnumerator::FILES, pattern);
  for (base::FilePath name = e.Next(); !name.empty(); name = e.Next()) {
    base::Time last_modified = GetFirstTimestamp(name);

    // If the first timestamp can't be retrieved, Use the timestamp one day
    // prior to the last modifiled time of the file (assumeing the file is
    // rotated daily).
    if (last_modified.is_null())
      last_modified =
          e.GetInfo().GetLastModifiedTime() - base::TimeDelta::FromDays(1);

    if (last_modified.is_null())
      continue;

    if (oldest_last_modified.is_null() || oldest_last_modified > last_modified)
      oldest_last_modified = last_modified;
  }

  return oldest_last_modified;
}

base::Time GetOldestModifiedTime(base::FilePath log_directory,
                                 const char* log_files[]) {
  base::Time oldest_last_modified;

  for (int i = 0; log_files[i] != NULL; i++) {
    base::Time last_modified =
        GetOldestTimestampFromLogFiles(log_directory, log_files[i]);

    if (last_modified.is_null())
      continue;

    if (oldest_last_modified.is_null() || oldest_last_modified > last_modified)
      oldest_last_modified = last_modified;
  }

  return oldest_last_modified;
}

base::Time GetOldestModifiedTime() {
  return GetOldestModifiedTime(kLogDir, kLogFiles);
}

// Extracts the boot ID from the givin boot ID entry.
base::Time ExtractTimestampString(const std::string& boot_id_entry) {
  base::Time time;

  if (boot_id_entry[26] == 'Z') {
    // Case of UTC time format like "2020-05-25T00:00:00.000000Z".
    std::string log_time = boot_id_entry.substr(0, kTimestampLength);

    bool result = base::Time::FromString(log_time.c_str(), &time);
    if (!result)
      return base::Time();

    return time;
  } else if (boot_id_entry[26] == '+' || boot_id_entry[26] == '-') {
    // Case of format with time-zone like "2020-05-25T00:00:00.000000+00:00".
    std::string log_time = boot_id_entry.substr(0, kLocalTimeTimestampLength);

    bool result = base::Time::FromString(log_time.c_str(), &time);
    if (!result)
      return base::Time();

    return time;
  }

  // Returning a null time as an error.
  return base::Time();
}
