// 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;
    }

    if (!BootRecords::IsValidBootId(e->message())) {
      continue;
    }

    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.
    if (boot_entry.boot_time() >= next_boot_time) {
      LOG(WARNING) << "Boot entries must be in an incremental order, but not: "
                   << boot_entry.boot_time() << " -> " << next_boot_time
                   << ". This "
                   << "entry is ignored.";
      continue;
    }

    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
