//===-- Statistics.h --------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TARGET_STATISTICS_H
#define LLDB_TARGET_STATISTICS_H

#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Stream.h"
#include "lldb/lldb-forward.h"
#include "llvm/Support/JSON.h"
#include <atomic>
#include <chrono>
#include <ratio>
#include <string>
#include <vector>

namespace lldb_private {

using StatsClock = std::chrono::high_resolution_clock;
using StatsTimepoint = std::chrono::time_point<StatsClock>;

class StatsDuration {
public:
  using Duration = std::chrono::duration<double>;

  Duration get() const {
    return Duration(InternalDuration(value.load(std::memory_order_relaxed)));
  }
  operator Duration() const { return get(); }

  StatsDuration &operator+=(Duration dur) {
    value.fetch_add(std::chrono::duration_cast<InternalDuration>(dur).count(),
                    std::memory_order_relaxed);
    return *this;
  }

private:
  using InternalDuration = std::chrono::duration<uint64_t, std::micro>;
  std::atomic<uint64_t> value{0};
};

/// A class that measures elapsed time in an exception safe way.
///
/// This is a RAII class is designed to help gather timing statistics within
/// LLDB where objects have optional Duration variables that get updated with
/// elapsed times. This helps LLDB measure statistics for many things that are
/// then reported in LLDB commands.
///
/// Objects that need to measure elapsed times should have a variable of type
/// "StatsDuration m_time_xxx;" which can then be used in the constructor of
/// this class inside a scope that wants to measure something:
///
///   ElapsedTime elapsed(m_time_xxx);
///   // Do some work
///
/// This class will increment the m_time_xxx variable with the elapsed time
/// when the object goes out of scope. The "m_time_xxx" variable will be
/// incremented when the class goes out of scope. This allows a variable to
/// measure something that might happen in stages at different times, like
/// resolving a breakpoint each time a new shared library is loaded.
class ElapsedTime {
public:
  /// Set to the start time when the object is created.
  StatsTimepoint m_start_time;
  /// Elapsed time in seconds to increment when this object goes out of scope.
  StatsDuration &m_elapsed_time;

public:
  ElapsedTime(StatsDuration &opt_time) : m_elapsed_time(opt_time) {
    m_start_time = StatsClock::now();
  }
  ~ElapsedTime() {
    StatsClock::duration elapsed = StatsClock::now() - m_start_time;
    m_elapsed_time += elapsed;
  }
};

/// A class to count success/fail statistics.
struct StatsSuccessFail {
  StatsSuccessFail(llvm::StringRef n) : name(n.str()) {}

  void NotifySuccess() { ++successes; }
  void NotifyFailure() { ++failures; }

  llvm::json::Value ToJSON() const;
  std::string name;
  uint32_t successes = 0;
  uint32_t failures = 0;
};

/// A class that represents statistics for a since lldb_private::Module.
struct ModuleStats {
  llvm::json::Value ToJSON() const;
  intptr_t identifier;
  std::string path;
  std::string uuid;
  std::string triple;
  // Path separate debug info file, or empty if none.
  std::string symfile_path;
  // If the debug info is contained in multiple files where each one is
  // represented as a separate lldb_private::Module, then these are the
  // identifiers of these modules in the global module list. This allows us to
  // track down all of the stats that contribute to this module.
  std::vector<intptr_t> symfile_modules;
  double symtab_parse_time = 0.0;
  double symtab_index_time = 0.0;
  double debug_parse_time = 0.0;
  double debug_index_time = 0.0;
  uint64_t debug_info_size = 0;
  bool symtab_loaded_from_cache = false;
  bool symtab_saved_to_cache = false;
  bool debug_info_index_loaded_from_cache = false;
  bool debug_info_index_saved_to_cache = false;
  bool debug_info_enabled = true;
  bool symtab_stripped = false;
};

struct ConstStringStats {
  llvm::json::Value ToJSON() const;
  ConstString::MemoryStats stats = ConstString::GetMemoryStats();
};

/// A class that represents statistics for a since lldb_private::Target.
class TargetStats {
public:
  llvm::json::Value ToJSON(Target &target);

  void SetLaunchOrAttachTime();
  void SetFirstPrivateStopTime();
  void SetFirstPublicStopTime();

  StatsDuration &GetCreateTime() { return m_create_time; }
  StatsSuccessFail &GetExpressionStats() { return m_expr_eval; }
  StatsSuccessFail &GetFrameVariableStats() { return m_frame_var; }

protected:
  StatsDuration m_create_time;
  llvm::Optional<StatsTimepoint> m_launch_or_attach_time;
  llvm::Optional<StatsTimepoint> m_first_private_stop_time;
  llvm::Optional<StatsTimepoint> m_first_public_stop_time;
  StatsSuccessFail m_expr_eval{"expressionEvaluation"};
  StatsSuccessFail m_frame_var{"frameVariable"};
  std::vector<intptr_t> m_module_identifiers;
  void CollectStats(Target &target);
};

class DebuggerStats {
public:
  static void SetCollectingStats(bool enable) { g_collecting_stats = enable; }
  static bool GetCollectingStats() { return g_collecting_stats; }

  /// Get metrics associated with one or all targets in a debugger in JSON
  /// format.
  ///
  /// \param debugger
  ///   The debugger to get the target list from if \a target is NULL.
  ///
  /// \param target
  ///   The single target to emit statistics for if non NULL, otherwise dump
  ///   statistics only for the specified target.
  ///
  /// \return
  ///     Returns a JSON value that contains all target metrics.
  static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target);

protected:
  // Collecting stats can be set to true to collect stats that are expensive
  // to collect. By default all stats that are cheap to collect are enabled.
  // This settings is here to maintain compatibility with "statistics enable"
  // and "statistics disable".
  static bool g_collecting_stats;
};

} // namespace lldb_private

#endif // LLDB_TARGET_STATISTICS_H
