// 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 <deque>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>

#include <fcntl.h>
#include <stdio.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"

#include "bootid-logger/bootid_logger.h"
#include "bootid-logger/constants.h"
#include "bootid-logger/timestamp_util.h"

#include <base/check_op.h>
#include <base/logging.h>

namespace {

constexpr char kBootIdProcPath[] = "/proc/sys/kernel/random/boot_id";

// Generate an entry in the boot entry format.
std::string GenerateBootEntryString(const std::string current_boot_id,
                                    const base::Time boot_time) {
  // Boot id must be 32 hexadecimal digits.
  CHECK_EQ(32u, current_boot_id.length());

  // TODO(crbug.com): Change the timezone from local to UTC.

  base::Time::Exploded exploded;
  boot_time.UTCExplode(&exploded);

  const std::string boot_time_str(base::StringPrintf(
      "%04d-%02d-%02dT%02d:%02d:%02d.%03d000Z", exploded.year, exploded.month,
      exploded.day_of_month, exploded.hour, exploded.minute, exploded.second,
      exploded.millisecond));
  CHECK_EQ(kTimestampLength, boot_time_str.size());

  const std::string boot_id_entry = boot_time_str + " " + kBootEntrySeverity +
                                    " " + kBootEntryPrefix +
                                    base::ToLowerASCII(current_boot_id);
  CHECK_EQ(kBootEntryLength, boot_id_entry.length());
  return boot_id_entry;
}

// Validate the given boot entry is valid (as an entry with UTC timestap).
bool ValidateBootEntryWithUTC(const std::string& boot_id_entry) {
  if (boot_id_entry.length() != kBootEntryLength)
    return false;

  if (boot_id_entry[kBootEntrySeverityOffset - 1] != ' ' ||
      boot_id_entry[kBootEntryPrefixOffset - 1] != ' ' ||
      boot_id_entry[kBootEntryBootIdOffset - 1] != ' ')
    return false;

  return true;
}

// Validate the given boot entry is valid (as an entry with local timestap).
bool ValidateBootEntryWithTimezone(const std::string& boot_id_entry) {
  if (boot_id_entry.length() != kBootEntryLocalTimeLength)
    return false;

  if (boot_id_entry[kBootEntryLocalTimeSeverityOffset - 1] != ' ' ||
      boot_id_entry[kBootEntryLocalTimeMessageOffset - 1] != ' ' ||
      boot_id_entry[kBootEntryLocalTimeBootIdOffset - 1] != ' ')
    return false;

  return true;
}

// Read previous entries from the log file (FD).
base::Optional<std::deque<std::string>> ReadPreviousBootEntries(
    const int fd,
    const base::Time first_timestamp_to_keep,
    int boot_log_max_entries) {
  std::deque<std::string> previous_boot_entries;

  struct stat st;
  fstat(fd, &st);
  const off_t length = st.st_size;

  if (length > 0) {
    // Here, we do mmap and stringstream to read lines.
    // We can't use ifstream here because we want to use fd for keeping locking
    // on the file.
    char* buffer =
        static_cast<char*>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0));
    if (buffer == NULL) {
      PLOG(FATAL) << "mmap failed";
      return base::nullopt;
    }

    // Set the buffer to the stream.
    std::istringstream ss(std::string(buffer, length));

    std::string s;
    while (std::getline(ss, s)) {
      // Skip an empty log.
      if (s.empty())
        continue;

      // Skip a duplicated entry.
      if (!previous_boot_entries.empty() && previous_boot_entries.back() == s)
        continue;

      // Skip an invalid entry.
      if (!ValidateBootEntry(s))
        continue;

      if (!first_timestamp_to_keep.is_null()) {
        base::Time time = ExtractTimestampString(s);
        // Skips the entry with older timestamp than |first_timestamp_to_keep|.
        if (!time.is_null() && time < first_timestamp_to_keep)
          continue;
      }

      previous_boot_entries.push_back(s);
    }

    munmap(buffer, length);

    // Truncate if the logs are overflown.
    while (previous_boot_entries.size() > (boot_log_max_entries - 1)) {
      previous_boot_entries.pop_front();
    }
  }

  return previous_boot_entries;
}

base::Time GetCurrentBootTime() {
  struct timespec boot_timespec;
  if (clock_gettime(CLOCK_BOOTTIME, &boot_timespec) == -1) {
    PLOG(FATAL) << "clock_gettime failed";
    exit(EXIT_FAILURE);
  }

  return base::Time::Now() - base::TimeDelta::FromTimeSpec(boot_timespec);
}

}  // anonymous namespace

// Validate the given boot entry is valid.
bool ValidateBootEntry(const std::string& boot_id_entry) {
  return ValidateBootEntryWithUTC(boot_id_entry) ||
         ValidateBootEntryWithTimezone(boot_id_entry);
}

// Extracts the boot ID from the givin boot ID entry.
std::string ExtractBootId(const std::string& boot_id_entry) {
  if (boot_id_entry.length() == kBootEntryLength)
    return boot_id_entry.substr(kBootEntryBootIdOffset, kBootIdLength);

  if (boot_id_entry.length() == kBootEntryLocalTimeLength)
    return boot_id_entry.substr(kBootEntryLocalTimeBootIdOffset, kBootIdLength);

  return "";
}

std::string GetCurrentBootId() {
  std::string boot_id;
  if (!base::ReadFileToString(base::FilePath(kBootIdProcPath), &boot_id)) {
    LOG(FATAL) << "Reading the log file failed";
    exit(EXIT_FAILURE);
  }
  base::RemoveChars(boot_id, "-\r\n", &boot_id);
  CHECK_EQ(kBootIdLength, boot_id.length());
  return boot_id;
}

bool WriteCurrentBootEntry(const base::FilePath& bootid_log_path,
                           const base::Time first_timestamp_to_keep,
                           const int max_entries) {
  std::string boot_id = GetCurrentBootId();
  base::Time boot_time = GetCurrentBootTime();

  return WriteBootEntry(bootid_log_path, boot_id, boot_time,
                        first_timestamp_to_keep, max_entries);
}

bool WriteBootEntry(const base::FilePath& bootid_log_path,
                    const std::string& current_boot_id,
                    const base::Time boot_time,
                    const base::Time first_timestamp_to_keep,
                    const int max_entries) {
  // Open the log file.
  base::ScopedFD fd(HANDLE_EINTR(
      open(bootid_log_path.value().c_str(), O_RDWR | O_CREAT | O_CLOEXEC,
           S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP /* 0644 */)));
  if (fd.get() == -1) {
    PLOG(FATAL) << "open failed";
    return false;
  }

  if (HANDLE_EINTR(flock(fd.get(), LOCK_EX)) == -1) {
    PLOG(FATAL) << "flock failed";
    return false;
  }

  auto ret =
      ReadPreviousBootEntries(fd.get(), first_timestamp_to_keep, max_entries);
  if (!ret.has_value()) {
    LOG(FATAL) << "Reading the log file failed";
    return false;
  }
  std::deque<std::string> previous_boot_entries = std::move(*ret);

  if (!previous_boot_entries.empty() &&
      ExtractBootId(previous_boot_entries.back()) == current_boot_id) {
    LOG(INFO) << "The current Boot ID does already exists in the log. New "
                 "entry is not added to prevent duplication.";
    // Returning true, since it is not an issue.
    return true;
  }

  const std::string boot_entry_str =
      GenerateBootEntryString(current_boot_id, boot_time);
  previous_boot_entries.push_back(boot_entry_str);

  // Update the current pos to the beginning of the file.
  if (lseek(fd.get(), 0, SEEK_SET) != 0) {
    PLOG(FATAL) << "lseek failed";
    return false;
  }

  // Shrink the file to zero.
  if (HANDLE_EINTR(ftruncate(fd.get(), 0)) != 0) {
    PLOG(FATAL) << "ftruncate failed";
    return false;
  }

  // Rewrite the existing entries.
  for (std::string boot_entry : previous_boot_entries) {
    boot_entry.append(1, '\n');

    if (!base::WriteFileDescriptor(fd.get(), boot_entry)) {
      PLOG(FATAL) << "Writing to the file failed";
      return false;
    }
  }

  // Automatically the file is closed and unlocked at the end of process.

  return true;
}
