// 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 "crash-reporter/crash_serializer.h"

#include <stdio.h>

#include <optional>
#include <string>
#include <utility>

#include <base/big_endian.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/strings/string_util.h>
#include <base/threading/platform_thread.h>
#include <base/time/default_clock.h>
#include <base/time/time.h>

#include "crash-reporter/crash_sender_base.h"
#include "crash-reporter/crash_sender_util.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/util.h"

namespace crash_serializer {

namespace {
void AddMetaField(crash::CrashInfo* info,
                  const std::string& key,
                  const std::string& value) {
  if (!base::IsStringUTF8(key)) {
    LOG(ERROR) << "key was not UTF8: " << key;
    return;
  }
  if (!base::IsStringUTF8(value)) {
    LOG(ERROR) << "value for key '" << key << "' was not UTF8";
    return;
  }
  crash::CrashMetadata* meta = info->add_fields();
  meta->set_key(key);
  meta->set_text(value);
}

std::optional<crash::CrashBlob> MakeBlob(const std::string& name,
                                         const base::FilePath& file) {
  if (!base::IsStringUTF8(name)) {
    LOG(ERROR) << "key was not UTF8: " << name;
    return std::nullopt;
  }
  std::string contents;
  if (!base::ReadFileToString(file, &contents)) {
    return std::nullopt;
  }
  crash::CrashBlob b;
  b.set_key(name);
  b.set_blob(contents);
  b.set_filename(file.BaseName().value());
  return b;
}

}  // namespace

Serializer::Serializer(std::unique_ptr<base::Clock> clock,
                       const Options& options)
    : util::SenderBase(std::move(clock), options),
      out_("/dev/stdout"),
      fetch_cores_(options.fetch_coredumps),
      max_message_size_bytes_(options.max_proto_bytes) {}

// The serializer doesn't remove crashes, so do nothing.
void Serializer::RecordCrashRemoveReason(CrashRemoveReason reason) {}

void Serializer::PickCrashFiles(const base::FilePath& crash_dir,
                                std::vector<util::MetaFile>* to_send) {
  std::vector<base::FilePath> meta_files = util::GetMetaFiles(crash_dir);

  for (const auto& meta_file : meta_files) {
    LOG(INFO) << "Checking metadata: " << meta_file.value();

    std::string reason;
    util::CrashInfo info;
    switch (EvaluateMetaFileMinimal(meta_file, /*allow_old_os_timestamps=*/true,
                                    &reason, &info,
                                    /*processing_file=*/nullptr)) {
      case kRemove:
        [[fallthrough]];  // Don't remove; rather, ignore the report.
      case kIgnore:
        LOG(INFO) << "Ignoring: " << reason;
        break;
      case kSend:
        to_send->push_back(std::make_pair(meta_file, std::move(info)));
        break;
      default:
        NOTREACHED();
    }
  }
}

void Serializer::SerializeCrashes(
    const std::vector<util::MetaFile>& crash_meta_files) {
  if (crash_meta_files.empty()) {
    return;
  }

  std::string client_id = util::GetClientId();

  base::File lock(AcquireLockFileOrDie());
  int64_t crash_id = -1;
  for (const auto& pair : crash_meta_files) {
    crash_id++;
    const base::FilePath& meta_file = pair.first;
    const util::CrashInfo& info = pair.second;
    LOG(INFO) << "Evaluating crash report: " << meta_file.value();

    base::TimeDelta sleep_time;
    if (!util::GetSleepTime(meta_file, /*max_spread_time=*/base::TimeDelta(),
                            hold_off_time_, &sleep_time)) {
      LOG(WARNING) << "Failed to compute sleep time for " << meta_file.value();
      continue;
    }

    LOG(INFO) << "Scheduled to send in " << sleep_time.InSeconds() << "s";
    lock.Close();  // Don't hold lock during sleep.
    if (!util::IsMock()) {
      base::PlatformThread::Sleep(sleep_time);
    } else if (!sleep_function_.is_null()) {
      sleep_function_.Run(sleep_time);
    }
    lock = AcquireLockFileOrDie();

    // Mark the crash as being processed so that if we crash, we don't try to
    // send the crash again.
    util::ScopedProcessingFile processing(meta_file);

    // User-specific crash reports become inaccessible if the user signs out
    // while sleeping, thus we need to check if the metadata is still
    // accessible.
    if (!base::PathExists(meta_file)) {
      LOG(INFO) << "Metadata is no longer accessible: " << meta_file.value();
      continue;
    }

    const util::CrashDetails details = {
        .meta_file = meta_file,
        .payload_file = info.payload_file,
        .payload_kind = info.payload_kind,
        .client_id = client_id,
        .metadata = info.metadata,
    };

    crash::FetchCrashesResponse resp;
    resp.set_crash_id(crash_id);
    std::vector<crash::CrashBlob> blobs;
    base::FilePath core_path;
    if (!SerializeCrash(details, resp.mutable_crash(), &blobs, &core_path)) {
      // If we cannot serialize the crash, give up -- there won't be anything to
      // write.
      LOG(ERROR) << "Failed to serialize " << meta_file.value();
      continue;
    }

    // Write the CrashInfo to output.
    if (!WriteFetchCrashesResponse(resp)) {
      // If we cannot write the CrashInfo, give up on the crash -- callers won't
      // be able to reconstruct anything useful from the report.
      LOG(ERROR) << "Failed to write CrashInfo proto for: " << meta_file.value()
                 << ". Giving up on this crash";
      continue;
    }

    if (!WriteBlobs(crash_id, blobs)) {
      // If this fails, keep trying to process the crash -- the coredump could
      // still be useful.
      LOG(ERROR) << "Failed to write blobs for " << meta_file.value();
    }

    if (!core_path.empty() && !WriteCoredump(crash_id, core_path)) {
      LOG(ERROR) << "Failed to write core for " << meta_file.value();
    }
  }
}

bool Serializer::SerializeCrash(const util::CrashDetails& details,
                                crash::CrashInfo* info,
                                std::vector<crash::CrashBlob>* blobs,
                                base::FilePath* core_path) {
  util::FullCrash crash = ReadMetaFile(details);

  // Add fields that are present directly in the FullCrash struct
  info->set_exec_name(crash.exec_name);
  AddMetaField(info, "board", crash.board);
  AddMetaField(info, "hwclass", crash.hwclass);
  info->set_prod(crash.prod);
  info->set_ver(crash.ver);
  info->set_sig(crash.sig);
  AddMetaField(info, "sig2", crash.sig);
  AddMetaField(info, "image_type", crash.image_type);
  AddMetaField(info, "boot_mode", crash.boot_mode);
  AddMetaField(info, "error_type", crash.error_type);
  AddMetaField(info, "guid", crash.guid);

  // Add fields from key_vals
  for (const auto& kv : crash.key_vals) {
    const std::string& key = kv.first;
    const std::string& val = kv.second;
    if (key == "in_progress_integration_test") {
      info->set_in_progress_integration_test(val);
    } else if (key == "collector") {
      info->set_collector(val);
    } else {
      AddMetaField(info, key, val);
    }
  }

  // Add payload file
  std::optional<crash::CrashBlob> payload =
      MakeBlob(crash.payload.first, crash.payload.second);
  if (!payload) {
    return false;
  }
  blobs->push_back(*payload);

  // Add files
  for (const auto& kv : crash.files) {
    std::optional<crash::CrashBlob> blob = MakeBlob(kv.first, kv.second);
    if (blob) {
      blobs->push_back(*blob);
    }
  }

  if (fetch_cores_) {
    base::FilePath maybe_core = details.meta_file.ReplaceExtension(".core");
    if (base::PathExists(maybe_core)) {
      *core_path = maybe_core;
    }
  }

  return true;
}

bool Serializer::WriteFetchCrashesResponse(
    const crash::FetchCrashesResponse& crash_data) {
  // Initialize string with the size and then append the proto to that so that
  // we get the data in a single buffer with no extra copies.
  size_t size = crash_data.ByteSizeLong();
  // Convert to a fixed size to ensure a consistent serialization format.
  static_assert(sizeof(size_t) <= sizeof(uint64_t),
                "size_t is too big to fit in 8 bytes");
  uint64_t size_uint64 = size;

  char size_bytes[sizeof(size_uint64)];
  base::WriteBigEndian(size_bytes, size_uint64);

  std::string buf(size_bytes, size_bytes + sizeof(size_uint64));
  if (!crash_data.AppendToString(&buf)) {
    LOG(ERROR) << "Failed to serialize proto to string";
    return false;
  }

  if (!base::AppendToFile(out_, buf)) {
    PLOG(ERROR) << "Failed to append";
    return false;
  }
  CHECK_EQ(buf.size(), size + sizeof(size_uint64));
  return true;
}

bool Serializer::WriteBlobs(int64_t crash_id,
                            const std::vector<crash::CrashBlob>& blobs) {
  crash::FetchCrashesResponse resp;
  resp.set_crash_id(crash_id);
  bool success = true;
  for (const auto& blob : blobs) {
    size_t actual_size = blob.blob().size();
    // Divide and round up to calculate the number of protos to split this
    // blob into.
    int proto_count =
        (actual_size + max_message_size_bytes_ - 1) / max_message_size_bytes_;

    crash::CrashBlob* send_blob = resp.mutable_blob();
    send_blob->set_key(blob.key());
    send_blob->set_filename(blob.filename());
    size_t offset = 0;
    for (int i = 0; i < proto_count; i++) {
      // Re-retrieve the pointer here because WriteFetchCrashesResponse might
      // invalidate it; see
      // https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#fields
      send_blob = resp.mutable_blob();
      CHECK_LE(offset, blob.blob().size());
      send_blob->set_blob(blob.blob().substr(offset, max_message_size_bytes_));

      if (!WriteFetchCrashesResponse(resp)) {
        LOG(ERROR) << "Failed to write blob: " << blob.key()
                   << " starting at offset: " << offset;
        // Don't continue with this blob -- even if we succeed at sending a
        // later chunk, callers won't be able to correctly reassemble the
        // data.
        success = false;
        break;
      }
      offset += max_message_size_bytes_;
    }
  }
  return success;
}

bool Serializer::WriteCoredump(int64_t crash_id, base::FilePath core_path) {
  crash::FetchCrashesResponse resp;
  resp.set_crash_id(crash_id);

  base::File core_file(core_path,
                       base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!core_file.IsValid()) {
    LOG(ERROR) << "Failed to open " << core_path.value() << " for reading: "
               << base::File::ErrorToString(core_file.error_details());
    return false;
  }

  int64_t size = core_file.GetLength();
  if (size < 0) {
    LOG(ERROR) << "Failed to get size for core file: " << core_path.value()
               << ": " << base::File::ErrorToString(core_file.error_details());
    return false;
  } else if (size == 0) {
    LOG(WARNING) << "Coredump " << core_path.value()
                 << " is empty. Proceeding anyway.";
  }

  int64_t total_read = 0;
  while (total_read < size) {
    std::vector<char> buf(max_message_size_bytes_);
    // Don't read the entire core into memory at once, as it could be multiple
    // GBs.
    int read = core_file.Read(total_read, buf.data(), max_message_size_bytes_);
    if (read < 0) {
      LOG(ERROR) << "Failed to read: " << core_path.value()
                 << "at offset: " << total_read << ": "
                 << base::File::ErrorToString(core_file.error_details());
      // Don't continue reading the core -- even if later calls succeed, the
      // caller won't be able to correctly reassemble the coredump.
      return false;
    }

    resp.set_core(buf.data(), read);
    if (!WriteFetchCrashesResponse(resp)) {
      LOG(ERROR) << "Failed to write core dump at offset " << total_read;
      // Don't continue reading the core -- even if later calls succeed, the
      // caller won't be able to correctly reassemble the coredump.
      return false;
    }

    total_read += read;
  }
  return true;
}

}  // namespace crash_serializer
