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

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

#include "croslog/log_line_reader.h"
#include "croslog/log_parser_syslog.h"

namespace croslog {

namespace {

// The maximum length of the boot log. The log must be less than 1000 lines,
// since it is trancated to 500 lines in log-bootid-on-boot.conf.
constexpr size_t kBootEntryMaxLen = 1000;

std::vector<BootRecords::BootEntry> ReadBootLogs(base::FilePath file_path) {
  LogLineReader reader(LogLineReader::Backend::FILE);

  std::vector<BootRecords::BootEntry> boot_log_entries;
  if (!base::PathExists(file_path))
    return boot_log_entries;

  LogParserSyslog parser;
  reader.OpenFile(std::move(file_path));

  while (true) {
    base::Optional<std::string> log = reader.Forward();
    if (!log.has_value()) {
      // EOF: finishes the read.
      break;
    }
    MaybeLogEntry e = parser.Parse(std::move(*log));
    if (!e.has_value()) {
      // Parse error: continuing the next line.
      continue;
    }
    DCHECK(BootRecords::IsValidBootId(e->message()));
    boot_log_entries.emplace_back(e->time(), e->message());
  }
  return boot_log_entries;
}

std::vector<BootRecords::BootRange> ConvertBootEntriesToRanges(
    const std::vector<BootRecords::BootEntry>& boot_log_entries) {
  std::vector<BootRecords::BootRange> boot_log_ranges;

  for (int i = 0; i < boot_log_entries.size(); i++) {
    const auto& boot_entry = boot_log_entries[i];
    base::Time next_boot_time = (i < (boot_log_entries.size() - 1))
                                    ? boot_log_entries[i + 1].boot_time()
                                    : base::Time::Max();

    // Boot times should be in an increasing order.
    DCHECK_LT(boot_entry.boot_time(), next_boot_time);
    boot_log_ranges.emplace_back(boot_entry.boot_time(), next_boot_time,
                                 boot_entry.boot_id());
  }

  return boot_log_ranges;
}

std::vector<BootRecords::BootRange> ReadBootRecords(base::FilePath file_path) {
  return ConvertBootEntriesToRanges(ReadBootLogs(file_path));
}

}  // anonymous namespace

// ============================================================================
// BootRecords::BootEntry implementation:

BootRecords::BootEntry::BootEntry(base::Time boot_time, std::string boot_id)
    : boot_time_(boot_time), boot_id_(std::move(boot_id)) {}

// ============================================================================
// BootRecords::BootRange implementation:

BootRecords::BootRange::BootRange(base::Time boot_time,
                                  base::Time next_boot_time,
                                  std::string boot_id)
    : boot_time_(boot_time),
      next_boot_time_(next_boot_time),
      boot_id_(std::move(boot_id)) {}

bool BootRecords::BootRange::Contains(base::Time time) const {
  return boot_time_ <= time && time < next_boot_time_;
}

bool operator==(BootRecords::BootRange const& a,
                BootRecords::BootRange const& b) {
  return a.boot_id() == b.boot_id() && a.boot_time() == b.boot_time() &&
         a.next_boot_time() == b.next_boot_time();
}

// ============================================================================
// BootRecords implementation:

// static
bool BootRecords::IsValidBootId(const std::string& boot_id) {
  if (boot_id.size() != 32)
    return false;

  for (int i = 0; i < 32; i++) {
    if (!(boot_id[i] >= '0' && boot_id[i] <= '9') &&
        !(boot_id[i] >= 'a' && boot_id[i] <= 'f')) {
      return false;
    }
  }
  return true;
}

BootRecords::BootRecords()
    : BootRecords(base::FilePath("/var/log/boot_id.log")) {}

BootRecords::BootRecords(base::FilePath file_path)
    : boot_ranges_(ReadBootRecords(file_path)) {
  DCHECK_GT(kBootEntryMaxLen, boot_ranges_.size());
}

BootRecords::BootRecords(std::vector<BootRecords::BootEntry> entries)
    : boot_ranges_(ConvertBootEntriesToRanges(entries)) {}

base::Optional<BootRecords::BootRange> BootRecords::GetBootRange(
    const std::string& boot_str) const {
  int boot_offset = 0;
  if (boot_str.empty() || base::StringToInt(boot_str, &boot_offset)) {
    if (boot_str.empty())
      boot_offset = 0;

    // The specified string may be a boot number.
    DCHECK_GT(kBootEntryMaxLen, boot_ranges_.size());

    int boot_offset_nth;
    if (boot_offset <= 0) {
      boot_offset_nth = boot_ranges_.size() + boot_offset - 1;
      if (boot_offset_nth < 0) {
        // Invalid offset.
        return base::nullopt;
      }
    } else {
      // Positive offset is not supported.
      // TODO(yoshiki): support positive offset values.
      return base::nullopt;
    }

    return boot_ranges_[boot_offset_nth];
  }

  if (IsValidBootId(boot_str)) {
    // The specified string may be a boot ID.
    for (int i = 0; i < boot_ranges_.size(); i++) {
      const auto& boot_entry = boot_ranges_[i];
      if (boot_entry.boot_id() != boot_str)
        continue;
      return boot_entry;
    }
  }

  // Invalid boot ID format, or no corresponding boot in the entries.
  return base::nullopt;
}

}  // namespace croslog
