//===-- StructuredDataDarwinLog.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 "StructuredDataDarwinLog.h"

#include <cstring>

#include <memory>
#include <sstream>

#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlanCallOnFunctionExit.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"

#define DARWIN_LOG_TYPE_VALUE "DarwinLog"

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(StructuredDataDarwinLog)

#pragma mark -
#pragma mark Anonymous Namespace

// Anonymous namespace

namespace sddarwinlog_private {
const uint64_t NANOS_PER_MICRO = 1000;
const uint64_t NANOS_PER_MILLI = NANOS_PER_MICRO * 1000;
const uint64_t NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
const uint64_t NANOS_PER_MINUTE = NANOS_PER_SECOND * 60;
const uint64_t NANOS_PER_HOUR = NANOS_PER_MINUTE * 60;

static bool DEFAULT_FILTER_FALLTHROUGH_ACCEPTS = true;

/// Global, sticky enable switch.  If true, the user has explicitly
/// run the enable command.  When a process launches or is attached to,
/// we will enable DarwinLog if either the settings for auto-enable is
/// on, or if the user had explicitly run enable at some point prior
/// to the launch/attach.
static bool s_is_explicitly_enabled;

class EnableOptions;
using EnableOptionsSP = std::shared_ptr<EnableOptions>;

using OptionsMap =
    std::map<DebuggerWP, EnableOptionsSP, std::owner_less<DebuggerWP>>;

static OptionsMap &GetGlobalOptionsMap() {
  static OptionsMap s_options_map;
  return s_options_map;
}

static std::mutex &GetGlobalOptionsMapLock() {
  static std::mutex s_options_map_lock;
  return s_options_map_lock;
}

EnableOptionsSP GetGlobalEnableOptions(const DebuggerSP &debugger_sp) {
  if (!debugger_sp)
    return EnableOptionsSP();

  std::lock_guard<std::mutex> locker(GetGlobalOptionsMapLock());
  OptionsMap &options_map = GetGlobalOptionsMap();
  DebuggerWP debugger_wp(debugger_sp);
  auto find_it = options_map.find(debugger_wp);
  if (find_it != options_map.end())
    return find_it->second;
  else
    return EnableOptionsSP();
}

void SetGlobalEnableOptions(const DebuggerSP &debugger_sp,
                            const EnableOptionsSP &options_sp) {
  std::lock_guard<std::mutex> locker(GetGlobalOptionsMapLock());
  OptionsMap &options_map = GetGlobalOptionsMap();
  DebuggerWP debugger_wp(debugger_sp);
  auto find_it = options_map.find(debugger_wp);
  if (find_it != options_map.end())
    find_it->second = options_sp;
  else
    options_map.insert(std::make_pair(debugger_wp, options_sp));
}

#pragma mark -
#pragma mark Settings Handling

/// Code to handle the StructuredDataDarwinLog settings

#define LLDB_PROPERTIES_darwinlog
#include "StructuredDataDarwinLogProperties.inc"

enum {
#define LLDB_PROPERTIES_darwinlog
#include "StructuredDataDarwinLogPropertiesEnum.inc"
};

class StructuredDataDarwinLogProperties : public Properties {
public:
  static ConstString &GetSettingName() {
    static ConstString g_setting_name("darwin-log");
    return g_setting_name;
  }

  StructuredDataDarwinLogProperties() : Properties() {
    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
    m_collection_sp->Initialize(g_darwinlog_properties);
  }

  ~StructuredDataDarwinLogProperties() override = default;

  bool GetEnableOnStartup() const {
    const uint32_t idx = ePropertyEnableOnStartup;
    return m_collection_sp->GetPropertyAtIndexAsBoolean(
        nullptr, idx, g_darwinlog_properties[idx].default_uint_value != 0);
  }

  llvm::StringRef GetAutoEnableOptions() const {
    const uint32_t idx = ePropertyAutoEnableOptions;
    return m_collection_sp->GetPropertyAtIndexAsString(
        nullptr, idx, g_darwinlog_properties[idx].default_cstr_value);
  }

  const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; }
};

static StructuredDataDarwinLogProperties &GetGlobalProperties() {
  static StructuredDataDarwinLogProperties g_settings;
  return g_settings;
}

const char *const s_filter_attributes[] = {
    "activity",       // current activity
    "activity-chain", // entire activity chain, each level separated by ':'
    "category",       // category of the log message
    "message",        // message contents, fully expanded
    "subsystem"       // subsystem of the log message

    // Consider implementing this action as it would be cheaper to filter.
    // "message" requires always formatting the message, which is a waste of
    // cycles if it ends up being rejected. "format",      // format string
    // used to format message text
};

static ConstString GetDarwinLogTypeName() {
  static const ConstString s_key_name("DarwinLog");
  return s_key_name;
}

static ConstString GetLogEventType() {
  static const ConstString s_event_type("log");
  return s_event_type;
}

class FilterRule;
using FilterRuleSP = std::shared_ptr<FilterRule>;

class FilterRule {
public:
  virtual ~FilterRule() = default;

  using OperationCreationFunc =
      std::function<FilterRuleSP(bool accept, size_t attribute_index,
                                 const std::string &op_arg, Status &error)>;

  static void RegisterOperation(ConstString operation,
                                const OperationCreationFunc &creation_func) {
    GetCreationFuncMap().insert(std::make_pair(operation, creation_func));
  }

  static FilterRuleSP CreateRule(bool match_accepts, size_t attribute,
                                 ConstString operation,
                                 const std::string &op_arg, Status &error) {
    // Find the creation func for this type of filter rule.
    auto map = GetCreationFuncMap();
    auto find_it = map.find(operation);
    if (find_it == map.end()) {
      error.SetErrorStringWithFormat("unknown filter operation \""
                                     "%s\"",
                                     operation.GetCString());
      return FilterRuleSP();
    }

    return find_it->second(match_accepts, attribute, op_arg, error);
  }

  StructuredData::ObjectSP Serialize() const {
    StructuredData::Dictionary *dict_p = new StructuredData::Dictionary();

    // Indicate whether this is an accept or reject rule.
    dict_p->AddBooleanItem("accept", m_accept);

    // Indicate which attribute of the message this filter references. This can
    // drop into the rule-specific DoSerialization if we get to the point where
    // not all FilterRule derived classes work on an attribute.  (e.g. logical
    // and/or and other compound operations).
    dict_p->AddStringItem("attribute", s_filter_attributes[m_attribute_index]);

    // Indicate the type of the rule.
    dict_p->AddStringItem("type", GetOperationType().GetCString());

    // Let the rule add its own specific details here.
    DoSerialization(*dict_p);

    return StructuredData::ObjectSP(dict_p);
  }

  virtual void Dump(Stream &stream) const = 0;

  ConstString GetOperationType() const { return m_operation; }

protected:
  FilterRule(bool accept, size_t attribute_index, ConstString operation)
      : m_accept(accept), m_attribute_index(attribute_index),
        m_operation(operation) {}

  virtual void DoSerialization(StructuredData::Dictionary &dict) const = 0;

  bool GetMatchAccepts() const { return m_accept; }

  const char *GetFilterAttribute() const {
    return s_filter_attributes[m_attribute_index];
  }

private:
  using CreationFuncMap = std::map<ConstString, OperationCreationFunc>;

  static CreationFuncMap &GetCreationFuncMap() {
    static CreationFuncMap s_map;
    return s_map;
  }

  const bool m_accept;
  const size_t m_attribute_index;
  const ConstString m_operation;
};

using FilterRules = std::vector<FilterRuleSP>;

class RegexFilterRule : public FilterRule {
public:
  static void RegisterOperation() {
    FilterRule::RegisterOperation(StaticGetOperation(), CreateOperation);
  }

  void Dump(Stream &stream) const override {
    stream.Printf("%s %s regex %s", GetMatchAccepts() ? "accept" : "reject",
                  GetFilterAttribute(), m_regex_text.c_str());
  }

protected:
  void DoSerialization(StructuredData::Dictionary &dict) const override {
    dict.AddStringItem("regex", m_regex_text);
  }

private:
  static FilterRuleSP CreateOperation(bool accept, size_t attribute_index,
                                      const std::string &op_arg,
                                      Status &error) {
    // We treat the op_arg as a regex.  Validate it.
    if (op_arg.empty()) {
      error.SetErrorString("regex filter type requires a regex "
                           "argument");
      return FilterRuleSP();
    }

    // Instantiate the regex so we can report any errors.
    auto regex = RegularExpression(op_arg);
    if (llvm::Error err = regex.GetError()) {
      error.SetErrorString(llvm::toString(std::move(err)));
      return FilterRuleSP();
    }

    // We passed all our checks, this appears fine.
    error.Clear();
    return FilterRuleSP(new RegexFilterRule(accept, attribute_index, op_arg));
  }

  static ConstString StaticGetOperation() {
    static ConstString s_operation("regex");
    return s_operation;
  }

  RegexFilterRule(bool accept, size_t attribute_index,
                  const std::string &regex_text)
      : FilterRule(accept, attribute_index, StaticGetOperation()),
        m_regex_text(regex_text) {}

  const std::string m_regex_text;
};

class ExactMatchFilterRule : public FilterRule {
public:
  static void RegisterOperation() {
    FilterRule::RegisterOperation(StaticGetOperation(), CreateOperation);
  }

  void Dump(Stream &stream) const override {
    stream.Printf("%s %s match %s", GetMatchAccepts() ? "accept" : "reject",
                  GetFilterAttribute(), m_match_text.c_str());
  }

protected:
  void DoSerialization(StructuredData::Dictionary &dict) const override {
    dict.AddStringItem("exact_text", m_match_text);
  }

private:
  static FilterRuleSP CreateOperation(bool accept, size_t attribute_index,
                                      const std::string &op_arg,
                                      Status &error) {
    if (op_arg.empty()) {
      error.SetErrorString("exact match filter type requires an "
                           "argument containing the text that must "
                           "match the specified message attribute.");
      return FilterRuleSP();
    }

    error.Clear();
    return FilterRuleSP(
        new ExactMatchFilterRule(accept, attribute_index, op_arg));
  }

  static ConstString StaticGetOperation() {
    static ConstString s_operation("match");
    return s_operation;
  }

  ExactMatchFilterRule(bool accept, size_t attribute_index,
                       const std::string &match_text)
      : FilterRule(accept, attribute_index, StaticGetOperation()),
        m_match_text(match_text) {}

  const std::string m_match_text;
};

static void RegisterFilterOperations() {
  ExactMatchFilterRule::RegisterOperation();
  RegexFilterRule::RegisterOperation();
}

// =========================================================================
// Commands
// =========================================================================

/// Provides the main on-off switch for enabling darwin logging.
///
/// It is valid to run the enable command when logging is already enabled.
/// This resets the logging with whatever settings are currently set.

static constexpr OptionDefinition g_enable_option_table[] = {
    // Source stream include/exclude options (the first-level filter). This one
    // should be made as small as possible as everything that goes through here
    // must be processed by the process monitor.
    {LLDB_OPT_SET_ALL, false, "any-process", 'a', OptionParser::eNoArgument,
     nullptr, {}, 0, eArgTypeNone,
     "Specifies log messages from other related processes should be "
     "included."},
    {LLDB_OPT_SET_ALL, false, "debug", 'd', OptionParser::eNoArgument, nullptr,
     {}, 0, eArgTypeNone,
     "Specifies debug-level log messages should be included.  Specifying"
     " --debug implies --info."},
    {LLDB_OPT_SET_ALL, false, "info", 'i', OptionParser::eNoArgument, nullptr,
     {}, 0, eArgTypeNone,
     "Specifies info-level log messages should be included."},
    {LLDB_OPT_SET_ALL, false, "filter", 'f', OptionParser::eRequiredArgument,
     nullptr, {}, 0, eArgRawInput,
     // There doesn't appear to be a great way for me to have these multi-line,
     // formatted tables in help.  This looks mostly right but there are extra
     // linefeeds added at seemingly random spots, and indentation isn't
     // handled properly on those lines.
     "Appends a filter rule to the log message filter chain.  Multiple "
     "rules may be added by specifying this option multiple times, "
     "once per filter rule.  Filter rules are processed in the order "
     "they are specified, with the --no-match-accepts setting used "
     "for any message that doesn't match one of the rules.\n"
     "\n"
     "    Filter spec format:\n"
     "\n"
     "    --filter \"{action} {attribute} {op}\"\n"
     "\n"
     "    {action} :=\n"
     "      accept |\n"
     "      reject\n"
     "\n"
     "    {attribute} :=\n"
     "       activity       |  // message's most-derived activity\n"
     "       activity-chain |  // message's {parent}:{child} activity\n"
     "       category       |  // message's category\n"
     "       message        |  // message's expanded contents\n"
     "       subsystem      |  // message's subsystem\n"
     "\n"
     "    {op} :=\n"
     "      match {exact-match-text} |\n"
     "      regex {search-regex}\n"
     "\n"
     "The regex flavor used is the C++ std::regex ECMAScript format.  "
     "Prefer character classes like [[:digit:]] to \\d and the like, as "
     "getting the backslashes escaped through properly is error-prone."},
    {LLDB_OPT_SET_ALL, false, "live-stream", 'l',
     OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
     "Specify whether logging events are live-streamed or buffered.  "
     "True indicates live streaming, false indicates buffered.  The "
     "default is true (live streaming).  Live streaming will deliver "
     "log messages with less delay, but buffered capture mode has less "
     "of an observer effect."},
    {LLDB_OPT_SET_ALL, false, "no-match-accepts", 'n',
     OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
     "Specify whether a log message that doesn't match any filter rule "
     "is accepted or rejected, where true indicates accept.  The "
     "default is true."},
    {LLDB_OPT_SET_ALL, false, "echo-to-stderr", 'e',
     OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
     "Specify whether os_log()/NSLog() messages are echoed to the "
     "target program's stderr.  When DarwinLog is enabled, we shut off "
     "the mirroring of os_log()/NSLog() to the program's stderr.  "
     "Setting this flag to true will restore the stderr mirroring."
     "The default is false."},
    {LLDB_OPT_SET_ALL, false, "broadcast-events", 'b',
     OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
     "Specify if the plugin should broadcast events.  Broadcasting "
     "log events is a requirement for displaying the log entries in "
     "LLDB command-line.  It is also required if LLDB clients want to "
     "process log events.  The default is true."},
    // Message formatting options
    {LLDB_OPT_SET_ALL, false, "timestamp-relative", 'r',
     OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone,
     "Include timestamp in the message header when printing a log "
     "message.  The timestamp is relative to the first displayed "
     "message."},
    {LLDB_OPT_SET_ALL, false, "subsystem", 's', OptionParser::eNoArgument,
     nullptr, {}, 0, eArgTypeNone,
     "Include the subsystem in the message header when displaying "
     "a log message."},
    {LLDB_OPT_SET_ALL, false, "category", 'c', OptionParser::eNoArgument,
     nullptr, {}, 0, eArgTypeNone,
     "Include the category in the message header when displaying "
     "a log message."},
    {LLDB_OPT_SET_ALL, false, "activity-chain", 'C', OptionParser::eNoArgument,
     nullptr, {}, 0, eArgTypeNone,
     "Include the activity parent-child chain in the message header "
     "when displaying a log message.  The activity hierarchy is "
     "displayed as {grandparent-activity}:"
     "{parent-activity}:{activity}[:...]."},
    {LLDB_OPT_SET_ALL, false, "all-fields", 'A', OptionParser::eNoArgument,
     nullptr, {}, 0, eArgTypeNone,
     "Shortcut to specify that all header fields should be displayed."}};

class EnableOptions : public Options {
public:
  EnableOptions()
      : Options(),
        m_filter_fall_through_accepts(DEFAULT_FILTER_FALLTHROUGH_ACCEPTS),
        m_filter_rules() {}

  void OptionParsingStarting(ExecutionContext *execution_context) override {
    m_include_debug_level = false;
    m_include_info_level = false;
    m_include_any_process = false;
    m_filter_fall_through_accepts = DEFAULT_FILTER_FALLTHROUGH_ACCEPTS;
    m_echo_to_stderr = false;
    m_display_timestamp_relative = false;
    m_display_subsystem = false;
    m_display_category = false;
    m_display_activity_chain = false;
    m_broadcast_events = true;
    m_live_stream = true;
    m_filter_rules.clear();
  }

  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                        ExecutionContext *execution_context) override {
    Status error;

    const int short_option = m_getopt_table[option_idx].val;
    switch (short_option) {
    case 'a':
      m_include_any_process = true;
      break;

    case 'A':
      m_display_timestamp_relative = true;
      m_display_category = true;
      m_display_subsystem = true;
      m_display_activity_chain = true;
      break;

    case 'b':
      m_broadcast_events =
          OptionArgParser::ToBoolean(option_arg, true, nullptr);
      break;

    case 'c':
      m_display_category = true;
      break;

    case 'C':
      m_display_activity_chain = true;
      break;

    case 'd':
      m_include_debug_level = true;
      break;

    case 'e':
      m_echo_to_stderr = OptionArgParser::ToBoolean(option_arg, false, nullptr);
      break;

    case 'f':
      return ParseFilterRule(option_arg);

    case 'i':
      m_include_info_level = true;
      break;

    case 'l':
      m_live_stream = OptionArgParser::ToBoolean(option_arg, false, nullptr);
      break;

    case 'n':
      m_filter_fall_through_accepts =
          OptionArgParser::ToBoolean(option_arg, true, nullptr);
      break;

    case 'r':
      m_display_timestamp_relative = true;
      break;

    case 's':
      m_display_subsystem = true;
      break;

    default:
      error.SetErrorStringWithFormat("unsupported option '%c'", short_option);
    }
    return error;
  }

  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
    return llvm::makeArrayRef(g_enable_option_table);
  }

  StructuredData::DictionarySP BuildConfigurationData(bool enabled) {
    StructuredData::DictionarySP config_sp(new StructuredData::Dictionary());

    // Set the basic enabled state.
    config_sp->AddBooleanItem("enabled", enabled);

    // If we're disabled, there's nothing more to add.
    if (!enabled)
      return config_sp;

    // Handle source stream flags.
    auto source_flags_sp =
        StructuredData::DictionarySP(new StructuredData::Dictionary());
    config_sp->AddItem("source-flags", source_flags_sp);

    source_flags_sp->AddBooleanItem("any-process", m_include_any_process);
    source_flags_sp->AddBooleanItem("debug-level", m_include_debug_level);
    // The debug-level flag, if set, implies info-level.
    source_flags_sp->AddBooleanItem("info-level", m_include_info_level ||
                                                      m_include_debug_level);
    source_flags_sp->AddBooleanItem("live-stream", m_live_stream);

    // Specify default filter rule (the fall-through)
    config_sp->AddBooleanItem("filter-fall-through-accepts",
                              m_filter_fall_through_accepts);

    // Handle filter rules
    if (!m_filter_rules.empty()) {
      auto json_filter_rules_sp =
          StructuredData::ArraySP(new StructuredData::Array);
      config_sp->AddItem("filter-rules", json_filter_rules_sp);
      for (auto &rule_sp : m_filter_rules) {
        if (!rule_sp)
          continue;
        json_filter_rules_sp->AddItem(rule_sp->Serialize());
      }
    }
    return config_sp;
  }

  bool GetIncludeDebugLevel() const { return m_include_debug_level; }

  bool GetIncludeInfoLevel() const {
    // Specifying debug level implies info level.
    return m_include_info_level || m_include_debug_level;
  }

  const FilterRules &GetFilterRules() const { return m_filter_rules; }

  bool GetFallthroughAccepts() const { return m_filter_fall_through_accepts; }

  bool GetEchoToStdErr() const { return m_echo_to_stderr; }

  bool GetDisplayTimestampRelative() const {
    return m_display_timestamp_relative;
  }

  bool GetDisplaySubsystem() const { return m_display_subsystem; }
  bool GetDisplayCategory() const { return m_display_category; }
  bool GetDisplayActivityChain() const { return m_display_activity_chain; }

  bool GetDisplayAnyHeaderFields() const {
    return m_display_timestamp_relative || m_display_activity_chain ||
           m_display_subsystem || m_display_category;
  }

  bool GetBroadcastEvents() const { return m_broadcast_events; }

private:
  Status ParseFilterRule(llvm::StringRef rule_text) {
    Status error;

    if (rule_text.empty()) {
      error.SetErrorString("invalid rule_text");
      return error;
    }

    // filter spec format:
    //
    // {action} {attribute} {op}
    //
    // {action} :=
    //   accept |
    //   reject
    //
    // {attribute} :=
    //   category       |
    //   subsystem      |
    //   activity       |
    //   activity-chain |
    //   message        |
    //   format
    //
    // {op} :=
    //   match {exact-match-text} |
    //   regex {search-regex}

    // Parse action.
    auto action_end_pos = rule_text.find(' ');
    if (action_end_pos == std::string::npos) {
      error.SetErrorStringWithFormat("could not parse filter rule "
                                     "action from \"%s\"",
                                     rule_text.str().c_str());
      return error;
    }
    auto action = rule_text.substr(0, action_end_pos);
    bool accept;
    if (action == "accept")
      accept = true;
    else if (action == "reject")
      accept = false;
    else {
      error.SetErrorString("filter action must be \"accept\" or \"deny\"");
      return error;
    }

    // parse attribute
    auto attribute_end_pos = rule_text.find(" ", action_end_pos + 1);
    if (attribute_end_pos == std::string::npos) {
      error.SetErrorStringWithFormat("could not parse filter rule "
                                     "attribute from \"%s\"",
                                     rule_text.str().c_str());
      return error;
    }
    auto attribute = rule_text.substr(action_end_pos + 1,
                                      attribute_end_pos - (action_end_pos + 1));
    auto attribute_index = MatchAttributeIndex(attribute);
    if (attribute_index < 0) {
      error.SetErrorStringWithFormat("filter rule attribute unknown: "
                                     "%s",
                                     attribute.str().c_str());
      return error;
    }

    // parse operation
    auto operation_end_pos = rule_text.find(" ", attribute_end_pos + 1);
    auto operation = rule_text.substr(
        attribute_end_pos + 1, operation_end_pos - (attribute_end_pos + 1));

    // add filter spec
    auto rule_sp = FilterRule::CreateRule(
        accept, attribute_index, ConstString(operation),
        std::string(rule_text.substr(operation_end_pos + 1)), error);

    if (rule_sp && error.Success())
      m_filter_rules.push_back(rule_sp);

    return error;
  }

  int MatchAttributeIndex(llvm::StringRef attribute_name) const {
    for (const auto &Item : llvm::enumerate(s_filter_attributes)) {
      if (attribute_name == Item.value())
        return Item.index();
    }

    // We didn't match anything.
    return -1;
  }

  bool m_include_debug_level = false;
  bool m_include_info_level = false;
  bool m_include_any_process = false;
  bool m_filter_fall_through_accepts;
  bool m_echo_to_stderr = false;
  bool m_display_timestamp_relative = false;
  bool m_display_subsystem = false;
  bool m_display_category = false;
  bool m_display_activity_chain = false;
  bool m_broadcast_events = true;
  bool m_live_stream = true;
  FilterRules m_filter_rules;
};

class EnableCommand : public CommandObjectParsed {
public:
  EnableCommand(CommandInterpreter &interpreter, bool enable, const char *name,
                const char *help, const char *syntax)
      : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable),
        m_options_sp(enable ? new EnableOptions() : nullptr) {}

protected:
  void AppendStrictSourcesWarning(CommandReturnObject &result,
                                  const char *source_name) {
    if (!source_name)
      return;

    // Check if we're *not* using strict sources.  If not, then the user is
    // going to get debug-level info anyways, probably not what they're
    // expecting. Unfortunately we can only fix this by adding an env var,
    // which would have had to have happened already.  Thus, a warning is the
    // best we can do here.
    StreamString stream;
    stream.Printf("darwin-log source settings specify to exclude "
                  "%s messages, but setting "
                  "'plugin.structured-data.darwin-log."
                  "strict-sources' is disabled.  This process will "
                  "automatically have %s messages included.  Enable"
                  " the property and relaunch the target binary to have"
                  " these messages excluded.",
                  source_name, source_name);
    result.AppendWarning(stream.GetString());
  }

  bool DoExecute(Args &command, CommandReturnObject &result) override {
    // First off, set the global sticky state of enable/disable based on this
    // command execution.
    s_is_explicitly_enabled = m_enable;

    // Next, if this is an enable, save off the option data. We will need it
    // later if a process hasn't been launched or attached yet.
    if (m_enable) {
      // Save off enabled configuration so we can apply these parsed options
      // the next time an attach or launch occurs.
      DebuggerSP debugger_sp =
          GetCommandInterpreter().GetDebugger().shared_from_this();
      SetGlobalEnableOptions(debugger_sp, m_options_sp);
    }

    // Now check if we have a running process.  If so, we should instruct the
    // process monitor to enable/disable DarwinLog support now.
    Target &target = GetSelectedOrDummyTarget();

    // Grab the active process.
    auto process_sp = target.GetProcessSP();
    if (!process_sp) {
      // No active process, so there is nothing more to do right now.
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
      return true;
    }

    // If the process is no longer alive, we can't do this now. We'll catch it
    // the next time the process is started up.
    if (!process_sp->IsAlive()) {
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
      return true;
    }

    // Get the plugin for the process.
    auto plugin_sp =
        process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
    if (!plugin_sp || (plugin_sp->GetPluginName() !=
                       StructuredDataDarwinLog::GetStaticPluginName())) {
      result.AppendError("failed to get StructuredDataPlugin for "
                         "the process");
    }
    StructuredDataDarwinLog &plugin =
        *static_cast<StructuredDataDarwinLog *>(plugin_sp.get());

    if (m_enable) {
      // Hook up the breakpoint for the process that detects when libtrace has
      // been sufficiently initialized to really start the os_log stream.  This
      // is insurance to assure us that logging is really enabled.  Requesting
      // that logging be enabled for a process before libtrace is initialized
      // results in a scenario where no errors occur, but no logging is
      // captured, either.  This step is to eliminate that possibility.
      plugin.AddInitCompletionHook(*process_sp);
    }

    // Send configuration to the feature by way of the process. Construct the
    // options we will use.
    auto config_sp = m_options_sp->BuildConfigurationData(m_enable);
    const Status error =
        process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);

    // Report results.
    if (!error.Success()) {
      result.AppendError(error.AsCString());
      // Our configuration failed, so we're definitely disabled.
      plugin.SetEnabled(false);
    } else {
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
      // Our configuration succeeded, so we're enabled/disabled per whichever
      // one this command is setup to do.
      plugin.SetEnabled(m_enable);
    }
    return result.Succeeded();
  }

  Options *GetOptions() override {
    // We don't have options when this represents disable.
    return m_enable ? m_options_sp.get() : nullptr;
  }

private:
  const bool m_enable;
  EnableOptionsSP m_options_sp;
};

/// Provides the status command.
class StatusCommand : public CommandObjectParsed {
public:
  StatusCommand(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "status",
                            "Show whether Darwin log supported is available"
                            " and enabled.",
                            "plugin structured-data darwin-log status") {}

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    auto &stream = result.GetOutputStream();

    // Figure out if we've got a process.  If so, we can tell if DarwinLog is
    // available for that process.
    Target &target = GetSelectedOrDummyTarget();
    auto process_sp = target.GetProcessSP();
    if (!process_sp) {
      stream.PutCString("Availability: unknown (requires process)\n");
      stream.PutCString("Enabled: not applicable "
                        "(requires process)\n");
    } else {
      auto plugin_sp =
          process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
      stream.Printf("Availability: %s\n",
                    plugin_sp ? "available" : "unavailable");
      llvm::StringRef plugin_name = StructuredDataDarwinLog::GetStaticPluginName();
      const bool enabled =
          plugin_sp ? plugin_sp->GetEnabled(ConstString(plugin_name)) : false;
      stream.Printf("Enabled: %s\n", enabled ? "true" : "false");
    }

    // Display filter settings.
    DebuggerSP debugger_sp =
        GetCommandInterpreter().GetDebugger().shared_from_this();
    auto options_sp = GetGlobalEnableOptions(debugger_sp);
    if (!options_sp) {
      // Nothing more to do.
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }

    // Print filter rules
    stream.PutCString("DarwinLog filter rules:\n");

    stream.IndentMore();

    if (options_sp->GetFilterRules().empty()) {
      stream.Indent();
      stream.PutCString("none\n");
    } else {
      // Print each of the filter rules.
      int rule_number = 0;
      for (auto rule_sp : options_sp->GetFilterRules()) {
        ++rule_number;
        if (!rule_sp)
          continue;

        stream.Indent();
        stream.Printf("%02d: ", rule_number);
        rule_sp->Dump(stream);
        stream.PutChar('\n');
      }
    }
    stream.IndentLess();

    // Print no-match handling.
    stream.Indent();
    stream.Printf("no-match behavior: %s\n",
                  options_sp->GetFallthroughAccepts() ? "accept" : "reject");

    result.SetStatus(eReturnStatusSuccessFinishResult);
    return true;
  }
};

/// Provides the darwin-log base command
class BaseCommand : public CommandObjectMultiword {
public:
  BaseCommand(CommandInterpreter &interpreter)
      : CommandObjectMultiword(interpreter, "plugin structured-data darwin-log",
                               "Commands for configuring Darwin os_log "
                               "support.",
                               "") {
    // enable
    auto enable_help = "Enable Darwin log collection, or re-enable "
                       "with modified configuration.";
    auto enable_syntax = "plugin structured-data darwin-log enable";
    auto enable_cmd_sp = CommandObjectSP(
        new EnableCommand(interpreter,
                          true, // enable
                          "enable", enable_help, enable_syntax));
    LoadSubCommand("enable", enable_cmd_sp);

    // disable
    auto disable_help = "Disable Darwin log collection.";
    auto disable_syntax = "plugin structured-data darwin-log disable";
    auto disable_cmd_sp = CommandObjectSP(
        new EnableCommand(interpreter,
                          false, // disable
                          "disable", disable_help, disable_syntax));
    LoadSubCommand("disable", disable_cmd_sp);

    // status
    auto status_cmd_sp = CommandObjectSP(new StatusCommand(interpreter));
    LoadSubCommand("status", status_cmd_sp);
  }
};

EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
  // We are abusing the options data model here so that we can parse options
  // without requiring the Debugger instance.

  // We have an empty execution context at this point.  We only want to parse
  // options, and we don't need any context to do this here. In fact, we want
  // to be able to parse the enable options before having any context.
  ExecutionContext exe_ctx;

  EnableOptionsSP options_sp(new EnableOptions());
  options_sp->NotifyOptionParsingStarting(&exe_ctx);

  CommandReturnObject result(debugger.GetUseColor());

  // Parse the arguments.
  auto options_property_sp =
      debugger.GetPropertyValue(nullptr, "plugin.structured-data.darwin-log."
                                         "auto-enable-options",
                                false, error);
  if (!error.Success())
    return EnableOptionsSP();
  if (!options_property_sp) {
    error.SetErrorString("failed to find option setting for "
                         "plugin.structured-data.darwin-log.");
    return EnableOptionsSP();
  }

  const char *enable_options =
      options_property_sp->GetAsString()->GetCurrentValue();
  Args args(enable_options);
  if (args.GetArgumentCount() > 0) {
    // Eliminate the initial '--' that would be required to set the settings
    // that themselves include '-' and/or '--'.
    const char *first_arg = args.GetArgumentAtIndex(0);
    if (first_arg && (strcmp(first_arg, "--") == 0))
      args.Shift();
  }

  bool require_validation = false;
  llvm::Expected<Args> args_or =
      options_sp->Parse(args, &exe_ctx, PlatformSP(), require_validation);
  if (!args_or) {
    LLDB_LOG_ERROR(
        log, args_or.takeError(),
        "Parsing plugin.structured-data.darwin-log.auto-enable-options value "
        "failed: {0}");
    return EnableOptionsSP();
  }

  if (!options_sp->VerifyOptions(result))
    return EnableOptionsSP();

  // We successfully parsed and validated the options.
  return options_sp;
}

bool RunEnableCommand(CommandInterpreter &interpreter) {
  StreamString command_stream;

  command_stream << "plugin structured-data darwin-log enable";
  auto enable_options = GetGlobalProperties().GetAutoEnableOptions();
  if (!enable_options.empty()) {
    command_stream << ' ';
    command_stream << enable_options;
  }

  // Run the command.
  CommandReturnObject return_object(interpreter.GetDebugger().GetUseColor());
  interpreter.HandleCommand(command_stream.GetData(), eLazyBoolNo,
                            return_object);
  return return_object.Succeeded();
}
}
using namespace sddarwinlog_private;

#pragma mark -
#pragma mark Public static API

// Public static API

void StructuredDataDarwinLog::Initialize() {
  RegisterFilterOperations();
  PluginManager::RegisterPlugin(
      GetStaticPluginName(), "Darwin os_log() and os_activity() support",
      &CreateInstance, &DebuggerInitialize, &FilterLaunchInfo);
}

void StructuredDataDarwinLog::Terminate() {
  PluginManager::UnregisterPlugin(&CreateInstance);
}

#pragma mark -
#pragma mark StructuredDataPlugin API

// StructuredDataPlugin API

bool StructuredDataDarwinLog::SupportsStructuredDataType(
    ConstString type_name) {
  return type_name == GetDarwinLogTypeName();
}

void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
    Process &process, ConstString type_name,
    const StructuredData::ObjectSP &object_sp) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (log) {
    StreamString json_stream;
    if (object_sp)
      object_sp->Dump(json_stream);
    else
      json_stream.PutCString("<null>");
    LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called with json: %s",
              __FUNCTION__, json_stream.GetData());
  }

  // Ignore empty structured data.
  if (!object_sp) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() StructuredData object "
              "is null",
              __FUNCTION__);
    return;
  }

  // Ignore any data that isn't for us.
  if (type_name != GetDarwinLogTypeName()) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() StructuredData type "
              "expected to be %s but was %s, ignoring",
              __FUNCTION__, GetDarwinLogTypeName().AsCString(),
              type_name.AsCString());
    return;
  }

  // Broadcast the structured data event if we have that enabled. This is the
  // way that the outside world (all clients) get access to this data.  This
  // plugin sets policy as to whether we do that.
  DebuggerSP debugger_sp = process.GetTarget().GetDebugger().shared_from_this();
  auto options_sp = GetGlobalEnableOptions(debugger_sp);
  if (options_sp && options_sp->GetBroadcastEvents()) {
    LLDB_LOGF(log, "StructuredDataDarwinLog::%s() broadcasting event",
              __FUNCTION__);
    process.BroadcastStructuredData(object_sp, shared_from_this());
  }

  // Later, hang on to a configurable amount of these and allow commands to
  // inspect, including showing backtraces.
}

static void SetErrorWithJSON(Status &error, const char *message,
                             StructuredData::Object &object) {
  if (!message) {
    error.SetErrorString("Internal error: message not set.");
    return;
  }

  StreamString object_stream;
  object.Dump(object_stream);
  object_stream.Flush();

  error.SetErrorStringWithFormat("%s: %s", message, object_stream.GetData());
}

Status StructuredDataDarwinLog::GetDescription(
    const StructuredData::ObjectSP &object_sp, lldb_private::Stream &stream) {
  Status error;

  if (!object_sp) {
    error.SetErrorString("No structured data.");
    return error;
  }

  // Log message payload objects will be dictionaries.
  const StructuredData::Dictionary *dictionary = object_sp->GetAsDictionary();
  if (!dictionary) {
    SetErrorWithJSON(error, "Structured data should have been a dictionary "
                            "but wasn't",
                     *object_sp);
    return error;
  }

  // Validate this is really a message for our plugin.
  ConstString type_name;
  if (!dictionary->GetValueForKeyAsString("type", type_name)) {
    SetErrorWithJSON(error, "Structured data doesn't contain mandatory "
                            "type field",
                     *object_sp);
    return error;
  }

  if (type_name != GetDarwinLogTypeName()) {
    // This is okay - it simply means the data we received is not a log
    // message.  We'll just format it as is.
    object_sp->Dump(stream);
    return error;
  }

  // DarwinLog dictionaries store their data
  // in an array with key name "events".
  StructuredData::Array *events = nullptr;
  if (!dictionary->GetValueForKeyAsArray("events", events) || !events) {
    SetErrorWithJSON(error, "Log structured data is missing mandatory "
                            "'events' field, expected to be an array",
                     *object_sp);
    return error;
  }

  events->ForEach(
      [&stream, &error, &object_sp, this](StructuredData::Object *object) {
        if (!object) {
          // Invalid.  Stop iterating.
          SetErrorWithJSON(error, "Log event entry is null", *object_sp);
          return false;
        }

        auto event = object->GetAsDictionary();
        if (!event) {
          // Invalid, stop iterating.
          SetErrorWithJSON(error, "Log event is not a dictionary", *object_sp);
          return false;
        }

        // If we haven't already grabbed the first timestamp value, do that
        // now.
        if (!m_recorded_first_timestamp) {
          uint64_t timestamp = 0;
          if (event->GetValueForKeyAsInteger("timestamp", timestamp)) {
            m_first_timestamp_seen = timestamp;
            m_recorded_first_timestamp = true;
          }
        }

        HandleDisplayOfEvent(*event, stream);
        return true;
      });

  stream.Flush();
  return error;
}

bool StructuredDataDarwinLog::GetEnabled(ConstString type_name) const {
  if (type_name.GetStringRef() == GetStaticPluginName())
    return m_is_enabled;
  else
    return false;
}

void StructuredDataDarwinLog::SetEnabled(bool enabled) {
  m_is_enabled = enabled;
}

void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
                                             ModuleList &module_list) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  LLDB_LOGF(log, "StructuredDataDarwinLog::%s called (process uid %u)",
            __FUNCTION__, process.GetUniqueID());

  // Check if we should enable the darwin log support on startup/attach.
  if (!GetGlobalProperties().GetEnableOnStartup() &&
      !s_is_explicitly_enabled) {
    // We're neither auto-enabled or explicitly enabled, so we shouldn't try to
    // enable here.
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s not applicable, we're not "
              "enabled (process uid %u)",
              __FUNCTION__, process.GetUniqueID());
    return;
  }

  // If we already added the breakpoint, we've got nothing left to do.
  {
    std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
    if (m_added_breakpoint) {
      LLDB_LOGF(log,
                "StructuredDataDarwinLog::%s process uid %u's "
                "post-libtrace-init breakpoint is already set",
                __FUNCTION__, process.GetUniqueID());
      return;
    }
  }

  // The logging support module name, specifies the name of the image name that
  // must be loaded into the debugged process before we can try to enable
  // logging.
  const char *logging_module_cstr =
      GetGlobalProperties().GetLoggingModuleName();
  if (!logging_module_cstr || (logging_module_cstr[0] == 0)) {
    // We need this.  Bail.
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s no logging module name "
              "specified, we don't know where to set a breakpoint "
              "(process uid %u)",
              __FUNCTION__, process.GetUniqueID());
    return;
  }

  const ConstString logging_module_name = ConstString(logging_module_cstr);

  // We need to see libtrace in the list of modules before we can enable
  // tracing for the target process.
  bool found_logging_support_module = false;
  for (size_t i = 0; i < module_list.GetSize(); ++i) {
    auto module_sp = module_list.GetModuleAtIndex(i);
    if (!module_sp)
      continue;

    auto &file_spec = module_sp->GetFileSpec();
    found_logging_support_module =
        (file_spec.GetLastPathComponent() == logging_module_name);
    if (found_logging_support_module)
      break;
  }

  if (!found_logging_support_module) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s logging module %s "
              "has not yet been loaded, can't set a breakpoint "
              "yet (process uid %u)",
              __FUNCTION__, logging_module_name.AsCString(),
              process.GetUniqueID());
    return;
  }

  // Time to enqueue the breakpoint so we can wait for logging support to be
  // initialized before we try to tap the libtrace stream.
  AddInitCompletionHook(process);
  LLDB_LOGF(log,
            "StructuredDataDarwinLog::%s post-init hook breakpoint "
            "set for logging module %s (process uid %u)",
            __FUNCTION__, logging_module_name.AsCString(),
            process.GetUniqueID());

  // We need to try the enable here as well, which will succeed in the event
  // that we're attaching to (rather than launching) the process and the
  // process is already past initialization time.  In that case, the completion
  // breakpoint will never get hit and therefore won't start that way.  It
  // doesn't hurt much beyond a bit of bandwidth if we end up doing this twice.
  // It hurts much more if we don't get the logging enabled when the user
  // expects it.
  EnableNow();
}

// public destructor

StructuredDataDarwinLog::~StructuredDataDarwinLog() {
  if (m_breakpoint_id != LLDB_INVALID_BREAK_ID) {
    ProcessSP process_sp(GetProcess());
    if (process_sp) {
      process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
      m_breakpoint_id = LLDB_INVALID_BREAK_ID;
    }
  }
}

#pragma mark -
#pragma mark Private instance methods

// Private constructors

StructuredDataDarwinLog::StructuredDataDarwinLog(const ProcessWP &process_wp)
    : StructuredDataPlugin(process_wp), m_recorded_first_timestamp(false),
      m_first_timestamp_seen(0), m_is_enabled(false),
      m_added_breakpoint_mutex(), m_added_breakpoint(),
      m_breakpoint_id(LLDB_INVALID_BREAK_ID) {}

// Private static methods

StructuredDataPluginSP
StructuredDataDarwinLog::CreateInstance(Process &process) {
  // Currently only Apple targets support the os_log/os_activity protocol.
  if (process.GetTarget().GetArchitecture().GetTriple().getVendor() ==
      llvm::Triple::VendorType::Apple) {
    auto process_wp = ProcessWP(process.shared_from_this());
    return StructuredDataPluginSP(new StructuredDataDarwinLog(process_wp));
  } else {
    return StructuredDataPluginSP();
  }
}

void StructuredDataDarwinLog::DebuggerInitialize(Debugger &debugger) {
  // Setup parent class first.
  StructuredDataPlugin::InitializeBasePluginForDebugger(debugger);

  // Get parent command.
  auto &interpreter = debugger.GetCommandInterpreter();
  llvm::StringRef parent_command_text = "plugin structured-data";
  auto parent_command =
      interpreter.GetCommandObjectForCommand(parent_command_text);
  if (!parent_command) {
    // Ut oh, parent failed to create parent command.
    // TODO log
    return;
  }

  auto command_name = "darwin-log";
  auto command_sp = CommandObjectSP(new BaseCommand(interpreter));
  bool result = parent_command->LoadSubCommand(command_name, command_sp);
  if (!result) {
    // TODO log it once we setup structured data logging
  }

  if (!PluginManager::GetSettingForPlatformPlugin(
          debugger, StructuredDataDarwinLogProperties::GetSettingName())) {
    const bool is_global_setting = true;
    PluginManager::CreateSettingForStructuredDataPlugin(
        debugger, GetGlobalProperties().GetValueProperties(),
        ConstString("Properties for the darwin-log"
                    " plug-in."),
        is_global_setting);
  }
}

Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info,
                                                 Target *target) {
  Status error;

  // If we're not debugging this launched process, there's nothing for us to do
  // here.
  if (!launch_info.GetFlags().AnySet(eLaunchFlagDebug))
    return error;

  // Darwin os_log() support automatically adds debug-level and info-level
  // messages when a debugger is attached to a process.  However, with
  // integrated support for debugging built into the command-line LLDB, the
  // user may specifically set to *not* include debug-level and info-level
  // content.  When the user is using the integrated log support, we want to
  // put the kabosh on that automatic adding of info and debug level. This is
  // done by adding an environment variable to the process on launch. (This
  // also means it is not possible to suppress this behavior if attaching to an
  // already-running app).
  // Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

  // If the target architecture is not one that supports DarwinLog, we have
  // nothing to do here.
  auto &triple = target ? target->GetArchitecture().GetTriple()
                        : launch_info.GetArchitecture().GetTriple();
  if (triple.getVendor() != llvm::Triple::Apple) {
    return error;
  }

  // If DarwinLog is not enabled (either by explicit user command or via the
  // auto-enable option), then we have nothing to do.
  if (!GetGlobalProperties().GetEnableOnStartup() &&
      !s_is_explicitly_enabled) {
    // Nothing to do, DarwinLog is not enabled.
    return error;
  }

  // If we don't have parsed configuration info, that implies we have enable-
  // on-startup set up, but we haven't yet attempted to run the enable command.
  if (!target) {
    // We really can't do this without a target.  We need to be able to get to
    // the debugger to get the proper options to do this right.
    // TODO log.
    error.SetErrorString("requires a target to auto-enable DarwinLog.");
    return error;
  }

  DebuggerSP debugger_sp = target->GetDebugger().shared_from_this();
  auto options_sp = GetGlobalEnableOptions(debugger_sp);
  if (!options_sp && debugger_sp) {
    options_sp = ParseAutoEnableOptions(error, *debugger_sp.get());
    if (!options_sp || !error.Success())
      return error;

    // We already parsed the options, save them now so we don't generate them
    // again until the user runs the command manually.
    SetGlobalEnableOptions(debugger_sp, options_sp);
  }

  if (!options_sp->GetEchoToStdErr()) {
    // The user doesn't want to see os_log/NSLog messages echo to stderr. That
    // mechanism is entirely separate from the DarwinLog support. By default we
    // don't want to get it via stderr, because that would be in duplicate of
    // the explicit log support here.

    // Here we need to strip out any OS_ACTIVITY_DT_MODE setting to prevent
    // echoing of os_log()/NSLog() to stderr in the target program.
    launch_info.GetEnvironment().erase("OS_ACTIVITY_DT_MODE");

    // We will also set the env var that tells any downstream launcher from
    // adding OS_ACTIVITY_DT_MODE.
    launch_info.GetEnvironment()["IDE_DISABLED_OS_ACTIVITY_DT_MODE"] = "1";
  }

  // Set the OS_ACTIVITY_MODE env var appropriately to enable/disable debug and
  // info level messages.
  const char *env_var_value;
  if (options_sp->GetIncludeDebugLevel())
    env_var_value = "debug";
  else if (options_sp->GetIncludeInfoLevel())
    env_var_value = "info";
  else
    env_var_value = "default";

  launch_info.GetEnvironment()["OS_ACTIVITY_MODE"] = env_var_value;

  return error;
}

bool StructuredDataDarwinLog::InitCompletionHookCallback(
    void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
    lldb::user_id_t break_loc_id) {
  // We hit the init function.  We now want to enqueue our new thread plan,
  // which will in turn enqueue a StepOut thread plan. When the StepOut
  // finishes and control returns to our new thread plan, that is the time when
  // we can execute our logic to enable the logging support.

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);

  // Get the current thread.
  if (!context) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: no context, "
              "ignoring",
              __FUNCTION__);
    return false;
  }

  // Get the plugin from the process.
  auto process_sp = context->exe_ctx_ref.GetProcessSP();
  if (!process_sp) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: invalid "
              "process in context, ignoring",
              __FUNCTION__);
    return false;
  }
  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %d",
            __FUNCTION__, process_sp->GetUniqueID());

  auto plugin_sp = process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
  if (!plugin_sp) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: no plugin for "
              "feature %s in process uid %u",
              __FUNCTION__, GetDarwinLogTypeName().AsCString(),
              process_sp->GetUniqueID());
    return false;
  }

  // Create the callback for when the thread plan completes.
  bool called_enable_method = false;
  const auto process_uid = process_sp->GetUniqueID();

  std::weak_ptr<StructuredDataPlugin> plugin_wp(plugin_sp);
  ThreadPlanCallOnFunctionExit::Callback callback =
      [plugin_wp, &called_enable_method, log, process_uid]() {
        LLDB_LOGF(log,
                  "StructuredDataDarwinLog::post-init callback: "
                  "called (process uid %u)",
                  process_uid);

        auto strong_plugin_sp = plugin_wp.lock();
        if (!strong_plugin_sp) {
          LLDB_LOGF(log,
                    "StructuredDataDarwinLog::post-init callback: "
                    "plugin no longer exists, ignoring (process "
                    "uid %u)",
                    process_uid);
          return;
        }
        // Make sure we only call it once, just in case the thread plan hits
        // the breakpoint twice.
        if (!called_enable_method) {
          LLDB_LOGF(log,
                    "StructuredDataDarwinLog::post-init callback: "
                    "calling EnableNow() (process uid %u)",
                    process_uid);
          static_cast<StructuredDataDarwinLog *>(strong_plugin_sp.get())
              ->EnableNow();
          called_enable_method = true;
        } else {
          // Our breakpoint was hit more than once.  Unexpected but no harm
          // done.  Log it.
          LLDB_LOGF(log,
                    "StructuredDataDarwinLog::post-init callback: "
                    "skipping EnableNow(), already called by "
                    "callback [we hit this more than once] "
                    "(process uid %u)",
                    process_uid);
        }
      };

  // Grab the current thread.
  auto thread_sp = context->exe_ctx_ref.GetThreadSP();
  if (!thread_sp) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: failed to "
              "retrieve the current thread from the execution "
              "context, nowhere to run the thread plan (process uid "
              "%u)",
              __FUNCTION__, process_sp->GetUniqueID());
    return false;
  }

  // Queue the thread plan.
  auto thread_plan_sp =
      ThreadPlanSP(new ThreadPlanCallOnFunctionExit(*thread_sp, callback));
  const bool abort_other_plans = false;
  thread_sp->QueueThreadPlan(thread_plan_sp, abort_other_plans);
  LLDB_LOGF(log,
            "StructuredDataDarwinLog::%s() queuing thread plan on "
            "trace library init method entry (process uid %u)",
            __FUNCTION__, process_sp->GetUniqueID());

  // We return false here to indicate that it isn't a public stop.
  return false;
}

void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called (process uid %u)",
            __FUNCTION__, process.GetUniqueID());

  // Make sure we haven't already done this.
  {
    std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
    if (m_added_breakpoint) {
      LLDB_LOGF(log,
                "StructuredDataDarwinLog::%s() ignoring request, "
                "breakpoint already set (process uid %u)",
                __FUNCTION__, process.GetUniqueID());
      return;
    }

    // We're about to do this, don't let anybody else try to do it.
    m_added_breakpoint = true;
  }

  // Set a breakpoint for the process that will kick in when libtrace has
  // finished its initialization.
  Target &target = process.GetTarget();

  // Build up the module list.
  FileSpecList module_spec_list;
  auto module_file_spec =
      FileSpec(GetGlobalProperties().GetLoggingModuleName());
  module_spec_list.Append(module_file_spec);

  // We aren't specifying a source file set.
  FileSpecList *source_spec_list = nullptr;

  const char *func_name = "_libtrace_init";
  const lldb::addr_t offset = 0;
  const LazyBool skip_prologue = eLazyBoolCalculate;
  // This is an internal breakpoint - the user shouldn't see it.
  const bool internal = true;
  const bool hardware = false;

  auto breakpoint_sp = target.CreateBreakpoint(
      &module_spec_list, source_spec_list, func_name, eFunctionNameTypeFull,
      eLanguageTypeC, offset, skip_prologue, internal, hardware);
  if (!breakpoint_sp) {
    // Huh?  Bail here.
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() failed to set "
              "breakpoint in module %s, function %s (process uid %u)",
              __FUNCTION__, GetGlobalProperties().GetLoggingModuleName(),
              func_name, process.GetUniqueID());
    return;
  }

  // Set our callback.
  breakpoint_sp->SetCallback(InitCompletionHookCallback, nullptr);
  m_breakpoint_id = breakpoint_sp->GetID();
  LLDB_LOGF(log,
            "StructuredDataDarwinLog::%s() breakpoint set in module %s,"
            "function %s (process uid %u)",
            __FUNCTION__, GetGlobalProperties().GetLoggingModuleName(),
            func_name, process.GetUniqueID());
}

void StructuredDataDarwinLog::DumpTimestamp(Stream &stream,
                                            uint64_t timestamp) {
  const uint64_t delta_nanos = timestamp - m_first_timestamp_seen;

  const uint64_t hours = delta_nanos / NANOS_PER_HOUR;
  uint64_t nanos_remaining = delta_nanos % NANOS_PER_HOUR;

  const uint64_t minutes = nanos_remaining / NANOS_PER_MINUTE;
  nanos_remaining = nanos_remaining % NANOS_PER_MINUTE;

  const uint64_t seconds = nanos_remaining / NANOS_PER_SECOND;
  nanos_remaining = nanos_remaining % NANOS_PER_SECOND;

  stream.Printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%09" PRIu64, hours,
                minutes, seconds, nanos_remaining);
}

size_t
StructuredDataDarwinLog::DumpHeader(Stream &output_stream,
                                    const StructuredData::Dictionary &event) {
  StreamString stream;

  ProcessSP process_sp = GetProcess();
  if (!process_sp) {
    // TODO log
    return 0;
  }

  DebuggerSP debugger_sp =
      process_sp->GetTarget().GetDebugger().shared_from_this();
  if (!debugger_sp) {
    // TODO log
    return 0;
  }

  auto options_sp = GetGlobalEnableOptions(debugger_sp);
  if (!options_sp) {
    // TODO log
    return 0;
  }

  // Check if we should even display a header.
  if (!options_sp->GetDisplayAnyHeaderFields())
    return 0;

  stream.PutChar('[');

  int header_count = 0;
  if (options_sp->GetDisplayTimestampRelative()) {
    uint64_t timestamp = 0;
    if (event.GetValueForKeyAsInteger("timestamp", timestamp)) {
      DumpTimestamp(stream, timestamp);
      ++header_count;
    }
  }

  if (options_sp->GetDisplayActivityChain()) {
    llvm::StringRef activity_chain;
    if (event.GetValueForKeyAsString("activity-chain", activity_chain) &&
        !activity_chain.empty()) {
      if (header_count > 0)
        stream.PutChar(',');

      // Display the activity chain, from parent-most to child-most activity,
      // separated by a colon (:).
      stream.PutCString("activity-chain=");
      stream.PutCString(activity_chain);
      ++header_count;
    }
  }

  if (options_sp->GetDisplaySubsystem()) {
    llvm::StringRef subsystem;
    if (event.GetValueForKeyAsString("subsystem", subsystem) &&
        !subsystem.empty()) {
      if (header_count > 0)
        stream.PutChar(',');
      stream.PutCString("subsystem=");
      stream.PutCString(subsystem);
      ++header_count;
    }
  }

  if (options_sp->GetDisplayCategory()) {
    llvm::StringRef category;
    if (event.GetValueForKeyAsString("category", category) &&
        !category.empty()) {
      if (header_count > 0)
        stream.PutChar(',');
      stream.PutCString("category=");
      stream.PutCString(category);
      ++header_count;
    }
  }
  stream.PutCString("] ");

  output_stream.PutCString(stream.GetString());

  return stream.GetSize();
}

size_t StructuredDataDarwinLog::HandleDisplayOfEvent(
    const StructuredData::Dictionary &event, Stream &stream) {
  // Check the type of the event.
  ConstString event_type;
  if (!event.GetValueForKeyAsString("type", event_type)) {
    // Hmm, we expected to get events that describe what they are.  Continue
    // anyway.
    return 0;
  }

  if (event_type != GetLogEventType())
    return 0;

  size_t total_bytes = 0;

  // Grab the message content.
  llvm::StringRef message;
  if (!event.GetValueForKeyAsString("message", message))
    return true;

  // Display the log entry.
  const auto len = message.size();

  total_bytes += DumpHeader(stream, event);

  stream.Write(message.data(), len);
  total_bytes += len;

  // Add an end of line.
  stream.PutChar('\n');
  total_bytes += sizeof(char);

  return total_bytes;
}

void StructuredDataDarwinLog::EnableNow() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);

  // Run the enable command.
  auto process_sp = GetProcess();
  if (!process_sp) {
    // Nothing to do.
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: failed to get "
              "valid process, skipping",
              __FUNCTION__);
    return;
  }
  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %u",
            __FUNCTION__, process_sp->GetUniqueID());

  // If we have configuration data, we can directly enable it now. Otherwise,
  // we need to run through the command interpreter to parse the auto-run
  // options (which is the only way we get here without having already-parsed
  // configuration data).
  DebuggerSP debugger_sp =
      process_sp->GetTarget().GetDebugger().shared_from_this();
  if (!debugger_sp) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: failed to get "
              "debugger shared pointer, skipping (process uid %u)",
              __FUNCTION__, process_sp->GetUniqueID());
    return;
  }

  auto options_sp = GetGlobalEnableOptions(debugger_sp);
  if (!options_sp) {
    // We haven't run the enable command yet.  Just do that now, it'll take
    // care of the rest.
    auto &interpreter = debugger_sp->GetCommandInterpreter();
    const bool success = RunEnableCommand(interpreter);
    if (log) {
      if (success)
        LLDB_LOGF(log,
                  "StructuredDataDarwinLog::%s() ran enable command "
                  "successfully for (process uid %u)",
                  __FUNCTION__, process_sp->GetUniqueID());
      else
        LLDB_LOGF(log,
                  "StructuredDataDarwinLog::%s() error: running "
                  "enable command failed (process uid %u)",
                  __FUNCTION__, process_sp->GetUniqueID());
    }
    // Report failures to the debugger error stream.
    auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
    if (error_stream_sp) {
      error_stream_sp->Printf("failed to configure DarwinLog "
                              "support\n");
      error_stream_sp->Flush();
    }
    return;
  }

  // We've previously been enabled. We will re-enable now with the previously
  // specified options.
  auto config_sp = options_sp->BuildConfigurationData(true);
  if (!config_sp) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() warning: failed to "
              "build configuration data for enable options, skipping "
              "(process uid %u)",
              __FUNCTION__, process_sp->GetUniqueID());
    return;
  }

  // We can run it directly.
  // Send configuration to the feature by way of the process.
  const Status error =
      process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);

  // Report results.
  if (!error.Success()) {
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() "
              "ConfigureStructuredData() call failed "
              "(process uid %u): %s",
              __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
    auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
    if (error_stream_sp) {
      error_stream_sp->Printf("failed to configure DarwinLog "
                              "support: %s\n",
                              error.AsCString());
      error_stream_sp->Flush();
    }
    m_is_enabled = false;
  } else {
    m_is_enabled = true;
    LLDB_LOGF(log,
              "StructuredDataDarwinLog::%s() success via direct "
              "configuration (process uid %u)",
              __FUNCTION__, process_sp->GetUniqueID());
  }
}
