//===-- Statistics.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/Statistics.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/StructuredData.h"

using namespace lldb;
using namespace lldb_private;
using namespace llvm;

static void EmplaceSafeString(llvm::json::Object &obj, llvm::StringRef key,
                              const std::string &str) {
  if (str.empty())
    return;
  if (LLVM_LIKELY(llvm::json::isUTF8(str)))
    obj.try_emplace(key, str);
  else
    obj.try_emplace(key, llvm::json::fixUTF8(str));
}

json::Value StatsSuccessFail::ToJSON() const {
  return json::Object{{"successes", successes}, {"failures", failures}};
}

static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end) {
  StatsDuration::Duration elapsed =
      end.time_since_epoch() - start.time_since_epoch();
  return elapsed.count();
}

void TargetStats::CollectStats(Target &target) {
  m_module_identifiers.clear();
  for (ModuleSP module_sp : target.GetImages().Modules())
    m_module_identifiers.emplace_back((intptr_t)module_sp.get());
}

json::Value ModuleStats::ToJSON() const {
  json::Object module;
  EmplaceSafeString(module, "path", path);
  EmplaceSafeString(module, "uuid", uuid);
  EmplaceSafeString(module, "triple", triple);
  module.try_emplace("identifier", identifier);
  module.try_emplace("symbolTableParseTime", symtab_parse_time);
  module.try_emplace("symbolTableIndexTime", symtab_index_time);
  module.try_emplace("symbolTableLoadedFromCache", symtab_loaded_from_cache);
  module.try_emplace("symbolTableSavedToCache", symtab_saved_to_cache);
  module.try_emplace("debugInfoParseTime", debug_parse_time);
  module.try_emplace("debugInfoIndexTime", debug_index_time);
  module.try_emplace("debugInfoByteSize", (int64_t)debug_info_size);
  module.try_emplace("debugInfoIndexLoadedFromCache",
                     debug_info_index_loaded_from_cache);
  module.try_emplace("debugInfoIndexSavedToCache",
                     debug_info_index_saved_to_cache);
  module.try_emplace("debugInfoEnabled", debug_info_enabled);
  module.try_emplace("debugInfoHadVariableErrors",
                     debug_info_had_variable_errors);
  module.try_emplace("debugInfoHadIncompleteTypes",
                     debug_info_had_incomplete_types);
  module.try_emplace("symbolTableStripped", symtab_stripped);
  module.try_emplace("symbolTableSymbolCount", symtab_symbol_count);
  module.try_emplace("dwoFileCount", dwo_stats.dwo_file_count);
  module.try_emplace("loadedDwoFileCount", dwo_stats.loaded_dwo_file_count);
  module.try_emplace("dwoErrorCount", dwo_stats.dwo_error_count);

  if (!symbol_locator_time.map.empty()) {
    json::Object obj;
    for (const auto &entry : symbol_locator_time.map)
      obj.try_emplace(entry.first().str(), entry.second);
    module.try_emplace("symbolLocatorTime", std::move(obj));
  }

  if (!symfile_path.empty())
    module.try_emplace("symbolFilePath", symfile_path);

  if (!symfile_modules.empty()) {
    json::Array symfile_ids;
    for (const auto symfile_id : symfile_modules)
      symfile_ids.emplace_back(symfile_id);
    module.try_emplace("symbolFileModuleIdentifiers", std::move(symfile_ids));
  }

  if (!type_system_stats.empty()) {
    json::Array type_systems;
    for (const auto &entry : type_system_stats) {
      json::Object obj;
      obj.try_emplace(entry.first().str(), entry.second);
      type_systems.emplace_back(std::move(obj));
    }
    module.try_emplace("typeSystemInfo", std::move(type_systems));
  }

  return module;
}

llvm::json::Value ConstStringStats::ToJSON() const {
  json::Object obj;
  obj.try_emplace<int64_t>("bytesTotal", stats.GetBytesTotal());
  obj.try_emplace<int64_t>("bytesUsed", stats.GetBytesUsed());
  obj.try_emplace<int64_t>("bytesUnused", stats.GetBytesUnused());
  return obj;
}

json::Value
TargetStats::ToJSON(Target &target,
                    const lldb_private::StatisticsOptions &options) {
  json::Object target_metrics_json;
  ProcessSP process_sp = target.GetProcessSP();
  const bool summary_only = options.GetSummaryOnly();
  const bool include_modules = options.GetIncludeModules();
  if (!summary_only) {
    CollectStats(target);

    json::Array json_module_uuid_array;
    for (auto module_identifier : m_module_identifiers)
      json_module_uuid_array.emplace_back(module_identifier);

    target_metrics_json.try_emplace(m_expr_eval.name, m_expr_eval.ToJSON());
    target_metrics_json.try_emplace(m_frame_var.name, m_frame_var.ToJSON());
    if (include_modules)
      target_metrics_json.try_emplace("moduleIdentifiers",
                                      std::move(json_module_uuid_array));

    if (m_launch_or_attach_time && m_first_private_stop_time) {
      double elapsed_time =
          elapsed(*m_launch_or_attach_time, *m_first_private_stop_time);
      target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time);
    }
    if (m_launch_or_attach_time && m_first_public_stop_time) {
      double elapsed_time =
          elapsed(*m_launch_or_attach_time, *m_first_public_stop_time);
      target_metrics_json.try_emplace("firstStopTime", elapsed_time);
    }
    target_metrics_json.try_emplace("targetCreateTime",
                                    m_create_time.get().count());

    if (m_load_core_time.get().count() > 0) {
      target_metrics_json.try_emplace("loadCoreTime",
                                      m_load_core_time.get().count());
    }

    json::Array breakpoints_array;
    double totalBreakpointResolveTime = 0.0;
    // Report both the normal breakpoint list and the internal breakpoint list.
    for (int i = 0; i < 2; ++i) {
      BreakpointList &breakpoints = target.GetBreakpointList(i == 1);
      std::unique_lock<std::recursive_mutex> lock;
      breakpoints.GetListMutex(lock);
      size_t num_breakpoints = breakpoints.GetSize();
      for (size_t i = 0; i < num_breakpoints; i++) {
        Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
        breakpoints_array.push_back(bp->GetStatistics());
        totalBreakpointResolveTime += bp->GetResolveTime().count();
      }
    }
    target_metrics_json.try_emplace("breakpoints",
                                    std::move(breakpoints_array));
    target_metrics_json.try_emplace("totalBreakpointResolveTime",
                                    totalBreakpointResolveTime);

    if (process_sp) {
      UnixSignalsSP unix_signals_sp = process_sp->GetUnixSignals();
      if (unix_signals_sp)
        target_metrics_json.try_emplace(
            "signals", unix_signals_sp->GetHitCountStatistics());
    }
  }

  // Counting "totalSharedLibraryEventHitCount" from breakpoints of kind
  // "shared-library-event".
  {
    uint32_t shared_library_event_breakpoint_hit_count = 0;
    // The "shared-library-event" is only found in the internal breakpoint list.
    BreakpointList &breakpoints = target.GetBreakpointList(/* internal */ true);
    std::unique_lock<std::recursive_mutex> lock;
    breakpoints.GetListMutex(lock);
    size_t num_breakpoints = breakpoints.GetSize();
    for (size_t i = 0; i < num_breakpoints; i++) {
      Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
      if (strcmp(bp->GetBreakpointKind(), "shared-library-event") == 0)
        shared_library_event_breakpoint_hit_count += bp->GetHitCount();
    }

    target_metrics_json.try_emplace("totalSharedLibraryEventHitCount",
                                    shared_library_event_breakpoint_hit_count);
  }

  if (process_sp) {
    uint32_t stop_id = process_sp->GetStopID();
    target_metrics_json.try_emplace("stopCount", stop_id);

    llvm::StringRef dyld_plugin_name;
    if (process_sp->GetDynamicLoader())
      dyld_plugin_name = process_sp->GetDynamicLoader()->GetPluginName();
    target_metrics_json.try_emplace("dyldPluginName", dyld_plugin_name);
  }
  target_metrics_json.try_emplace("sourceMapDeduceCount",
                                  m_source_map_deduce_count);
  target_metrics_json.try_emplace("sourceRealpathAttemptCount",
                                  m_source_realpath_attempt_count);
  target_metrics_json.try_emplace("sourceRealpathCompatibleCount",
                                  m_source_realpath_compatible_count);
  target_metrics_json.try_emplace("summaryProviderStatistics",
                                  target.GetSummaryStatisticsCache().ToJSON());
  return target_metrics_json;
}

void TargetStats::Reset(Target &target) {
  m_launch_or_attach_time.reset();
  m_first_private_stop_time.reset();
  m_first_public_stop_time.reset();
  // Report both the normal breakpoint list and the internal breakpoint list.
  for (int i = 0; i < 2; ++i) {
    BreakpointList &breakpoints = target.GetBreakpointList(i == 1);
    std::unique_lock<std::recursive_mutex> lock;
    breakpoints.GetListMutex(lock);
    size_t num_breakpoints = breakpoints.GetSize();
    for (size_t i = 0; i < num_breakpoints; i++) {
      Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
      bp->ResetStatistics();
    }
  }
  target.GetSummaryStatisticsCache().Reset();
}

void TargetStats::SetLaunchOrAttachTime() {
  m_launch_or_attach_time = StatsClock::now();
  m_first_private_stop_time = std::nullopt;
}

void TargetStats::SetFirstPrivateStopTime() {
  // Launching and attaching has many paths depending on if synchronous mode
  // was used or if we are stopping at the entry point or not. Only set the
  // first stop time if it hasn't already been set.
  if (!m_first_private_stop_time)
    m_first_private_stop_time = StatsClock::now();
}

void TargetStats::SetFirstPublicStopTime() {
  // Launching and attaching has many paths depending on if synchronous mode
  // was used or if we are stopping at the entry point or not. Only set the
  // first stop time if it hasn't already been set.
  if (!m_first_public_stop_time)
    m_first_public_stop_time = StatsClock::now();
}

void TargetStats::IncreaseSourceMapDeduceCount() {
  ++m_source_map_deduce_count;
}

void TargetStats::IncreaseSourceRealpathAttemptCount(uint32_t count) {
  m_source_realpath_attempt_count += count;
}

void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) {
  m_source_realpath_compatible_count += count;
}

bool DebuggerStats::g_collecting_stats = false;

void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) {
  std::lock_guard<std::recursive_mutex> guard(
      Module::GetAllocationModuleCollectionMutex());
  const uint64_t num_modules = target != nullptr
                                   ? target->GetImages().GetSize()
                                   : Module::GetNumberAllocatedModules();
  for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
    Module *module = target != nullptr
                         ? target->GetImages().GetModuleAtIndex(image_idx).get()
                         : Module::GetAllocatedModuleAtIndex(image_idx);
    if (module == nullptr)
      continue;
    module->ResetStatistics();
  }
  if (target)
    target->ResetStatistics();
  else {
    for (const auto &target : debugger.GetTargetList().Targets())
      target->ResetStatistics();
  }
}

llvm::json::Value DebuggerStats::ReportStatistics(
    Debugger &debugger, Target *target,
    const lldb_private::StatisticsOptions &options) {

  const bool summary_only = options.GetSummaryOnly();
  const bool load_all_debug_info = options.GetLoadAllDebugInfo();
  const bool include_targets = options.GetIncludeTargets();
  const bool include_modules = options.GetIncludeModules();
  const bool include_transcript = options.GetIncludeTranscript();
  const bool include_plugins = options.GetIncludePlugins();

  json::Array json_targets;
  json::Array json_modules;
  StatisticsMap symbol_locator_total_time;
  double symtab_parse_time = 0.0;
  double symtab_index_time = 0.0;
  double debug_parse_time = 0.0;
  double debug_index_time = 0.0;
  uint32_t symtabs_loaded = 0;
  uint32_t symtabs_loaded_from_cache = 0;
  uint32_t symtabs_saved_to_cache = 0;
  uint32_t debug_index_loaded = 0;
  uint32_t debug_index_saved = 0;
  uint64_t debug_info_size = 0;

  std::lock_guard<std::recursive_mutex> guard(
      Module::GetAllocationModuleCollectionMutex());
  const uint64_t num_modules = target != nullptr
                                   ? target->GetImages().GetSize()
                                   : Module::GetNumberAllocatedModules();
  uint32_t num_debug_info_enabled_modules = 0;
  uint32_t num_modules_has_debug_info = 0;
  uint32_t num_modules_with_variable_errors = 0;
  uint32_t num_modules_with_incomplete_types = 0;
  uint32_t num_stripped_modules = 0;
  uint32_t symtab_symbol_count = 0;
  DWOStats total_dwo_stats;
  for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
    Module *module = target != nullptr
                         ? target->GetImages().GetModuleAtIndex(image_idx).get()
                         : Module::GetAllocatedModuleAtIndex(image_idx);
    ModuleStats module_stat;
    module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count();
    module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();
    module_stat.symbol_locator_time = module->GetSymbolLocatorStatistics();
    symbol_locator_total_time.merge(module_stat.symbol_locator_time);
    Symtab *symtab = module->GetSymtab(/*can_create=*/false);
    if (symtab) {
      module_stat.symtab_symbol_count = symtab->GetNumSymbols();
      symtab_symbol_count += module_stat.symtab_symbol_count;
      ++symtabs_loaded;
      module_stat.symtab_loaded_from_cache = symtab->GetWasLoadedFromCache();
      if (module_stat.symtab_loaded_from_cache)
        ++symtabs_loaded_from_cache;
      module_stat.symtab_saved_to_cache = symtab->GetWasSavedToCache();
      if (module_stat.symtab_saved_to_cache)
        ++symtabs_saved_to_cache;
    }
    SymbolFile *sym_file = module->GetSymbolFile(/*can_create=*/false);
    if (sym_file) {
      if (!summary_only) {
        if (sym_file->GetObjectFile() != module->GetObjectFile())
          module_stat.symfile_path =
              sym_file->GetObjectFile()->GetFileSpec().GetPath();
        ModuleList symbol_modules = sym_file->GetDebugInfoModules();
        for (const auto &symbol_module : symbol_modules.Modules())
          module_stat.symfile_modules.push_back((intptr_t)symbol_module.get());
      }
      DWOStats current_dwo_stats = sym_file->GetDwoStats();
      module_stat.dwo_stats += current_dwo_stats;
      total_dwo_stats += current_dwo_stats;
      module_stat.debug_info_index_loaded_from_cache =
          sym_file->GetDebugInfoIndexWasLoadedFromCache();
      if (module_stat.debug_info_index_loaded_from_cache)
        ++debug_index_loaded;
      module_stat.debug_info_index_saved_to_cache =
          sym_file->GetDebugInfoIndexWasSavedToCache();
      if (module_stat.debug_info_index_saved_to_cache)
        ++debug_index_saved;
      module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count();
      module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count();
      module_stat.debug_info_size =
          sym_file->GetDebugInfoSize(load_all_debug_info);
      module_stat.symtab_stripped = module->GetObjectFile()->IsStripped();
      if (module_stat.symtab_stripped)
        ++num_stripped_modules;
      module_stat.debug_info_enabled = sym_file->GetLoadDebugInfoEnabled() &&
                                       module_stat.debug_info_size > 0;
      module_stat.debug_info_had_variable_errors =
          sym_file->GetDebugInfoHadFrameVariableErrors();
      if (module_stat.debug_info_enabled)
        ++num_debug_info_enabled_modules;
      if (module_stat.debug_info_size > 0)
        ++num_modules_has_debug_info;
      if (module_stat.debug_info_had_variable_errors)
        ++num_modules_with_variable_errors;
    }
    symtab_parse_time += module_stat.symtab_parse_time;
    symtab_index_time += module_stat.symtab_index_time;
    debug_parse_time += module_stat.debug_parse_time;
    debug_index_time += module_stat.debug_index_time;
    debug_info_size += module_stat.debug_info_size;
    module->ForEachTypeSystem([&](lldb::TypeSystemSP ts) {
      if (auto stats = ts->ReportStatistics())
        module_stat.type_system_stats.insert({ts->GetPluginName(), *stats});
      if (ts->GetHasForcefullyCompletedTypes())
        module_stat.debug_info_had_incomplete_types = true;
      return true;
    });
    if (module_stat.debug_info_had_incomplete_types)
      ++num_modules_with_incomplete_types;

    if (include_modules) {
      module_stat.identifier = (intptr_t)module;
      module_stat.path = module->GetFileSpec().GetPath();
      if (ConstString object_name = module->GetObjectName()) {
        module_stat.path.append(1, '(');
        module_stat.path.append(object_name.GetStringRef().str());
        module_stat.path.append(1, ')');
      }
      module_stat.uuid = module->GetUUID().GetAsString();
      module_stat.triple = module->GetArchitecture().GetTriple().str();
      json_modules.emplace_back(module_stat.ToJSON());
    }
  }

  json::Object global_stats{
      {"totalSymbolTableParseTime", symtab_parse_time},
      {"totalSymbolTableIndexTime", symtab_index_time},
      {"totalSymbolTablesLoaded", symtabs_loaded},
      {"totalSymbolTablesLoadedFromCache", symtabs_loaded_from_cache},
      {"totalSymbolTablesSavedToCache", symtabs_saved_to_cache},
      {"totalDebugInfoParseTime", debug_parse_time},
      {"totalDebugInfoIndexTime", debug_index_time},
      {"totalDebugInfoIndexLoadedFromCache", debug_index_loaded},
      {"totalDebugInfoIndexSavedToCache", debug_index_saved},
      {"totalDebugInfoByteSize", debug_info_size},
      {"totalModuleCount", num_modules},
      {"totalModuleCountHasDebugInfo", num_modules_has_debug_info},
      {"totalModuleCountWithVariableErrors", num_modules_with_variable_errors},
      {"totalModuleCountWithIncompleteTypes",
       num_modules_with_incomplete_types},
      {"totalDebugInfoEnabled", num_debug_info_enabled_modules},
      {"totalSymbolTableStripped", num_stripped_modules},
      {"totalSymbolTableSymbolCount", symtab_symbol_count},
      {"totalLoadedDwoFileCount", total_dwo_stats.loaded_dwo_file_count},
      {"totalDwoFileCount", total_dwo_stats.dwo_file_count},
      {"totalDwoErrorCount", total_dwo_stats.dwo_error_count},
  };

  if (include_targets) {
    if (target) {
      json_targets.emplace_back(target->ReportStatistics(options));
    } else {
      for (const auto &target : debugger.GetTargetList().Targets())
        json_targets.emplace_back(target->ReportStatistics(options));
    }
    global_stats.try_emplace("targets", std::move(json_targets));
  }

  if (!symbol_locator_total_time.map.empty()) {
    json::Object obj;
    for (const auto &entry : symbol_locator_total_time.map)
      obj.try_emplace(entry.first().str(), entry.second);
    global_stats.try_emplace("totalSymbolLocatorTime", std::move(obj));
  }

  ConstStringStats const_string_stats;
  json::Object json_memory{
      {"strings", const_string_stats.ToJSON()},
  };
  global_stats.try_emplace("memory", std::move(json_memory));
  if (!summary_only) {
    json::Value cmd_stats = debugger.GetCommandInterpreter().GetStatistics();
    global_stats.try_emplace("commands", std::move(cmd_stats));
  }

  if (include_modules) {
    global_stats.try_emplace("modules", std::move(json_modules));
  }

  if (include_transcript) {
    // When transcript is available, add it to the to-be-returned statistics.
    //
    // NOTE:
    // When the statistics is polled by an LLDB command:
    // - The transcript in the returned statistics *will NOT* contain the
    //   returned statistics itself (otherwise infinite recursion).
    // - The returned statistics *will* be written to the internal transcript
    //   buffer. It *will* appear in the next statistcs or transcript poll.
    //
    // For example, let's say the following commands are run in order:
    // - "version"
    // - "statistics dump"  <- call it "A"
    // - "statistics dump"  <- call it "B"
    // The output of "A" will contain the transcript of "version" and
    // "statistics dump" (A), with the latter having empty output. The output
    // of B will contain the trascnript of "version", "statistics dump" (A),
    // "statistics dump" (B), with A's output populated and B's output empty.
    const StructuredData::Array &transcript =
        debugger.GetCommandInterpreter().GetTranscript();
    if (transcript.GetSize() != 0) {
      std::string buffer;
      llvm::raw_string_ostream ss(buffer);
      json::OStream json_os(ss);
      transcript.Serialize(json_os);
      if (auto json_transcript = llvm::json::parse(buffer))
        global_stats.try_emplace("transcript",
                                 std::move(json_transcript.get()));
    }
  }

  if (include_plugins) {
    global_stats.try_emplace("plugins", PluginManager::GetJSON());
  }

  return std::move(global_stats);
}

llvm::json::Value SummaryStatistics::ToJSON() const {
  return json::Object{{
      {"name", GetName()},
      {"type", GetSummaryKindName()},
      {"count", GetSummaryCount()},
      {"totalTime", GetTotalTime()},
  }};
}

json::Value SummaryStatisticsCache::ToJSON() {
  std::lock_guard<std::mutex> guard(m_map_mutex);
  json::Array json_summary_stats;
  for (const auto &summary_stat : m_summary_stats_map)
    json_summary_stats.emplace_back(summary_stat.second->ToJSON());

  return json_summary_stats;
}

void SummaryStatisticsCache::Reset() {
  for (const auto &summary_stat : m_summary_stats_map)
    summary_stat.second->Reset();
}
