// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// A utility for printing the contents of a postmortem stability minidump.

#include <windows.h>  // NOLINT

#include <dbghelp.h>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "components/browser_watcher/stability_report.pb.h"

namespace {

const char kUsage[] =
    "Usage: %ls --minidump=<minidump file>\n"
    "\n"
    "  Dumps the contents of a postmortem minidump in a human readable way.\n";

bool ParseCommandLine(const base::CommandLine* cmd,
                      base::FilePath* minidump_path) {
  *minidump_path = cmd->GetSwitchValuePath("minidump");
  if (minidump_path->empty()) {
    LOG(ERROR) << "Missing minidump file.\n";
    LOG(ERROR) << base::StringPrintf(kUsage, cmd->GetProgram().value().c_str());
    return false;
  }
  return true;
}

void Indent(FILE* out, int indent_level) {
  DCHECK(out);
  for (int i = 0; i < indent_level; ++i)
    fprintf(out, "  ");
}

void PrintUserData(
    FILE* out,
    int indent_level,
    const google::protobuf::Map<std::string, browser_watcher::TypedValue>&
        user_data) {
  DCHECK(out);
  Indent(out, indent_level);
  fprintf(out, "User data (%zu)\n", user_data.size());
  for (const auto& kv : user_data) {
    Indent(out, indent_level + 1);
    fprintf(out, "%s : ", kv.first.c_str());
    const browser_watcher::TypedValue& value = kv.second;
    switch (kv.second.value_case()) {
      case browser_watcher::TypedValue::kBytesValue: {
        const std::string& bytes_value = value.bytes_value();
        for (size_t i = 0; i < bytes_value.size(); ++i)
          fprintf(out, "%02X ", bytes_value.at(i));
        fprintf(out, "\n");
        break;
      }
      case browser_watcher::TypedValue::kBytesReference:
        fprintf(out, "bytes reference (address: %llX, size: %llX)\n",
                value.bytes_reference().address(),
                value.bytes_reference().size());
        break;
      case browser_watcher::TypedValue::kStringValue:
        fprintf(out, "\"%s\"\n", value.string_value().c_str());
        break;
      case browser_watcher::TypedValue::kStringReference:
        fprintf(out, "string reference (address: %llX, size: %llX)\n",
                value.string_reference().address(),
                value.string_reference().size());
        break;
      case browser_watcher::TypedValue::kCharValue:
        fprintf(out, "'%s'\n", value.char_value().c_str());
        break;
      case browser_watcher::TypedValue::kBoolValue:
        fprintf(out, "%s\n", value.bool_value() ? "true" : "false");
        break;
      case browser_watcher::TypedValue::kSignedValue:
        fprintf(out, "%lld\n", value.signed_value());
        break;
      case browser_watcher::TypedValue::kUnsignedValue:
        fprintf(out, "%llu\n", value.unsigned_value());
        break;
      case browser_watcher::TypedValue::VALUE_NOT_SET:
        fprintf(out, "<not set>\n");
        break;
    }
  }
}

void PrintActivity(FILE* out,
                   int indent_level,
                   const browser_watcher::Activity& activity) {
  DCHECK(out);
  Indent(out, indent_level);
  fprintf(out, "Activity\n");
  Indent(out, indent_level + 1);
  fprintf(out, "type: %d\n", activity.type());
  Indent(out, indent_level + 1);
  fprintf(out, "time: %lld\n", activity.time());
  Indent(out, indent_level + 1);
  fprintf(out, "address: %llX\n", activity.address());
  switch (activity.type()) {
    case browser_watcher::Activity::UNKNOWN:
      break;
    case browser_watcher::Activity::ACT_TASK_RUN:
      Indent(out, indent_level + 1);
      fprintf(out, "origin_address: %llX\n", activity.origin_address());
      fprintf(out, "task_sequence_id: %lld\n", activity.task_sequence_id());
      break;
    case browser_watcher::Activity::ACT_LOCK_ACQUIRE:
      Indent(out, indent_level + 1);
      fprintf(out, "lock_address: %llX\n", activity.lock_address());
      break;
    case browser_watcher::Activity::ACT_EVENT_WAIT:
      Indent(out, indent_level + 1);
      fprintf(out, "event_address: %llX\n", activity.event_address());
      break;
    case browser_watcher::Activity::ACT_THREAD_JOIN:
      Indent(out, indent_level + 1);
      fprintf(out, "thread_id: %lld\n", activity.thread_id());
      break;
    case browser_watcher::Activity::ACT_PROCESS_WAIT:
      Indent(out, indent_level + 1);
      fprintf(out, "process_id: %lld\n", activity.process_id());
      break;
    case browser_watcher::Activity::ACT_GENERIC:
      Indent(out, indent_level + 1);
      fprintf(out, "id: %u, data: %d\n", activity.generic_id(),
              activity.generic_data());
      break;
  }

  PrintUserData(out, indent_level + 1, activity.user_data());
}

void PrintProcessState(FILE* out,
                       const browser_watcher::ProcessState& process) {
  std::string process_type;
  switch (process.process_type()) {
    case browser_watcher::ProcessState::UNKNOWN_PROCESS:
      process_type = "unknown type";
      break;
    case browser_watcher::ProcessState::BROWSER_PROCESS:
      process_type = "browser";
      break;
    case browser_watcher::ProcessState::WATCHER_PROCESS:
      process_type = "watcher";
      break;
    default:
      base::SStringPrintf(&process_type, "process type %d",
                          process.process_type());
      break;
  }

  fprintf(out, "Process %lld (%s, %d threads)\n", process.process_id(),
          process_type.c_str(), process.threads_size());

  if (process.has_memory_state() &&
      process.memory_state().has_windows_memory()) {
    const auto& windows_memory = process.memory_state().windows_memory();
    if (windows_memory.has_process_private_usage()) {
      fprintf(out, "process_private_usage: %u pages\n",
              windows_memory.process_private_usage());
    }
    if (windows_memory.has_process_peak_workingset_size()) {
      fprintf(out, "process_peak_workingset_size: %u pages\n",
              windows_memory.process_peak_workingset_size());
    }
    if (windows_memory.has_process_peak_pagefile_usage()) {
      fprintf(out, "process_peak_pagefile_usage: %u pages\n",
              windows_memory.process_peak_pagefile_usage());
    }
    if (windows_memory.has_process_allocation_attempt()) {
      fprintf(out, "process_allocation_attempt: %u bytes\n",
              windows_memory.process_allocation_attempt());
    }
    if (windows_memory.has_process_handle_count()) {
      fprintf(out, "process_handle_count: %u handles\n",
              windows_memory.process_handle_count());
    }
  }

  for (const browser_watcher::ThreadState& thread : process.threads()) {
    fprintf(out, "Thread %lld (%s) : %d activities\n", thread.thread_id(),
            thread.thread_name().c_str(), thread.activity_count());
    for (const browser_watcher::Activity& activity : thread.activities())
      PrintActivity(out, 1, activity);
  }

  PrintUserData(out, 1, process.data());
}

// TODO(manzagop): flesh out as StabilityReport gets fleshed out.
void PrintReport(FILE* out, const browser_watcher::StabilityReport& report) {
  if (report.has_system_memory_state() &&
      report.system_memory_state().has_windows_memory()) {
    const auto& windows_memory = report.system_memory_state().windows_memory();

    if (windows_memory.has_system_commit_limit()) {
      fprintf(out, "system_commit_limit: %u pages\n",
              windows_memory.system_commit_limit());
    }
    if (windows_memory.has_system_commit_remaining()) {
      fprintf(out, "system_commit_remaining: %u pages\n",
              windows_memory.system_commit_remaining());
    }
    if (windows_memory.has_system_handle_count()) {
      fprintf(out, "system_handle_count: %u handles\n",
              windows_memory.system_handle_count());
    }
  }
  PrintUserData(out, 0, report.global_data());
  for (int i = 0; i < report.process_states_size(); ++i) {
    const browser_watcher::ProcessState process = report.process_states(i);
    PrintProcessState(out, process);
  }
}

bool GetStabilityStreamRvaAndSize(RVA directory_rva,
                                  ULONG32 stream_count,
                                  FILE* file,
                                  RVA* report_rva,
                                  ULONG32* report_size_bytes) {
  std::vector<MINIDUMP_DIRECTORY> directory;
  directory.resize(stream_count);

  CHECK_EQ(0, fseek(file, directory_rva, SEEK_SET));
  CHECK_EQ(stream_count, fread(directory.data(), sizeof(MINIDUMP_DIRECTORY),
                               stream_count, file));

  for (const MINIDUMP_DIRECTORY& entry : directory) {
    constexpr ULONG32 kStabilityStream = static_cast<ULONG32>(0x4B6B0002);
    if (entry.StreamType == kStabilityStream) {
      *report_rva = entry.Location.Rva;
      *report_size_bytes = entry.Location.DataSize;
      return true;
    }
  }

  return false;
}

int Main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);

  // Get the dump.
  base::FilePath minidump_path;
  if (!ParseCommandLine(base::CommandLine::ForCurrentProcess(), &minidump_path))
    return 1;

  // Read the minidump to extract the proto.
  base::ScopedFILE minidump_file;
  minidump_file.reset(base::OpenFile(minidump_path, "rb"));
  CHECK(minidump_file.get());

  // Read the header.
  // TODO(manzagop): leverage Crashpad to do this.
  MINIDUMP_HEADER header = {};
  CHECK_EQ(1U, fread(&header, sizeof(header), 1U, minidump_file.get()));
  CHECK_EQ(static_cast<ULONG32>(MINIDUMP_SIGNATURE), header.Signature);
  fprintf(stdout, "Number of streams: %u\n", header.NumberOfStreams);
  RVA directory_rva = header.StreamDirectoryRva;

  RVA report_rva;
  ULONG32 report_size_bytes;
  CHECK(GetStabilityStreamRvaAndSize(directory_rva, header.NumberOfStreams,
                                     minidump_file.get(), &report_rva,
                                     &report_size_bytes));

  // Read the serialized stability report.
  std::string serialized_report;
  serialized_report.resize(report_size_bytes);
  CHECK_EQ(0, fseek(minidump_file.get(), report_rva, SEEK_SET));
  CHECK_EQ(report_size_bytes, fread(&serialized_report.at(0), 1,
                                    report_size_bytes, minidump_file.get()));

  browser_watcher::StabilityReport report;
  CHECK(report.ParseFromString(serialized_report));

  // Note: we can't use the usual protocol buffer human readable API due to
  // the use of optimize_for = LITE_RUNTIME.
  PrintReport(stdout, report);

  return 0;
}

}  // namespace

int main(int argc, char** argv) {
  return Main(argc, argv);
}
