//===-- BreakpointOptions.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_BREAKPOINT_BREAKPOINTOPTIONS_H
#define LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H

#include <memory>
#include <string>

#include "lldb/Utility/Baton.h"
#include "lldb/Utility/Flags.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

/// \class BreakpointOptions BreakpointOptions.h
/// "lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a
/// breakpoint or breakpoint location.

class BreakpointOptions {
friend class BreakpointLocation;
friend class BreakpointName;
friend class lldb_private::BreakpointOptionGroup;
friend class Breakpoint;

public:
  enum OptionKind {
    eCallback     = 1 << 0,
    eEnabled      = 1 << 1,
    eOneShot      = 1 << 2,
    eIgnoreCount  = 1 << 3,
    eThreadSpec   = 1 << 4,
    eCondition    = 1 << 5,
    eAutoContinue = 1 << 6,
    eAllOptions   = (eCallback | eEnabled | eOneShot | eIgnoreCount | eThreadSpec
                     | eCondition | eAutoContinue)
  };
  struct CommandData {
    CommandData() {}

    CommandData(const StringList &user_source, lldb::ScriptLanguage interp)
        : user_source(user_source), interpreter(interp), stop_on_error(true) {}

    virtual ~CommandData() = default;

    static const char *GetSerializationKey() { return "BKPTCMDData"; }

    StructuredData::ObjectSP SerializeToStructuredData();

    static std::unique_ptr<CommandData>
    CreateFromStructuredData(const StructuredData::Dictionary &options_dict,
                             Status &error);

    StringList user_source;
    std::string script_source;
    enum lldb::ScriptLanguage interpreter =
        lldb::eScriptLanguageNone; // eScriptLanguageNone means command
                                   // interpreter.
    bool stop_on_error = true;

  private:
    enum class OptionNames : uint32_t {
      UserSource = 0,
      Interpreter,
      StopOnError,
      LastOptionName
    };

    static const char
        *g_option_names[static_cast<uint32_t>(OptionNames::LastOptionName)];

    static const char *GetKey(OptionNames enum_value) {
      return g_option_names[static_cast<uint32_t>(enum_value)];
    }
  };

  class CommandBaton : public TypedBaton<CommandData> {
  public:
    explicit CommandBaton(std::unique_ptr<CommandData> Data)
        : TypedBaton(std::move(Data)) {}

    void GetDescription(llvm::raw_ostream &s, lldb::DescriptionLevel level,
                        unsigned indentation) const override;
  };

  typedef std::shared_ptr<CommandBaton> CommandBatonSP;

  // Constructors and Destructors

  /// This constructor allows you to specify all the breakpoint options except
  /// the callback.  That one is more complicated, and better to do by hand.
  ///
  /// \param[in] condition
  ///    The expression which if it evaluates to \b true if we are to stop
  ///
  /// \param[in] enabled
  ///    Is this breakpoint enabled.
  ///
  /// \param[in] ignore
  ///    How many breakpoint hits we should ignore before stopping.
  ///
  /// \param[in] one_shot
  ///    Should this breakpoint delete itself after being hit once.
  ///
  /// \param[in] auto_continue
  ///    Should this breakpoint auto-continue after running its commands.
  ///
  BreakpointOptions(const char *condition, bool enabled = true,
                    int32_t ignore = 0, bool one_shot = false,
                    bool auto_continue = false);

  /// Breakpoints make options with all flags set.  Locations and Names make
  /// options with no flags set.
  BreakpointOptions(bool all_flags_set);
  BreakpointOptions(const BreakpointOptions &rhs);

  virtual ~BreakpointOptions();

  static std::unique_ptr<BreakpointOptions>
  CreateFromStructuredData(Target &target,
                           const StructuredData::Dictionary &data_dict,
                           Status &error);

  virtual StructuredData::ObjectSP SerializeToStructuredData();

  static const char *GetSerializationKey() { return "BKPTOptions"; }

  // Operators
  const BreakpointOptions &operator=(const BreakpointOptions &rhs);

  /// Copy over only the options set in the incoming BreakpointOptions.
  void CopyOverSetOptions(const BreakpointOptions &rhs);

  // Callbacks
  //
  // Breakpoint callbacks come in two forms, synchronous and asynchronous.
  // Synchronous callbacks will get run before any of the thread plans are
  // consulted, and if they return false the target will continue "under the
  // radar" of the thread plans.  There are a couple of restrictions to
  // synchronous callbacks:
  // 1) They should NOT resume the target themselves.
  //     Just return false if you want the target to restart.
  // 2) Breakpoints with synchronous callbacks can't have conditions
  //    (or rather, they can have them, but they won't do anything.
  //    Ditto with ignore counts, etc...  You are supposed to control that all
  //    through the callback.
  // Asynchronous callbacks get run as part of the "ShouldStop" logic in the
  // thread plan.  The logic there is:
  //   a) If the breakpoint is thread specific and not for this thread, continue
  //   w/o running the callback.
  //      NB. This is actually enforced underneath the breakpoint system, the
  //      Process plugin is expected to
  //      call BreakpointSite::IsValidForThread, and set the thread's StopInfo
  //      to "no reason".  That way,
  //      thread displays won't show stops for breakpoints not for that
  //      thread...
  //   b) If the ignore count says we shouldn't stop, then ditto.
  //   c) If the condition says we shouldn't stop, then ditto.
  //   d) Otherwise, the callback will get run, and if it returns true we will
  //      stop, and if false we won't.
  //  The asynchronous callback can run the target itself, but at present that
  //  should be the last action the callback does.  We will relax this condition
  //  at some point, but it will take a bit of plumbing to get that to work.
  //

  /// Adds a callback to the breakpoint option set.
  ///
  /// \param[in] callback
  ///    The function to be called when the breakpoint gets hit.
  ///
  /// \param[in] baton_sp
  ///    A baton which will get passed back to the callback when it is invoked.
  ///
  /// \param[in] synchronous
  ///    Whether this is a synchronous or asynchronous callback.  See discussion
  ///    above.
  void SetCallback(BreakpointHitCallback callback,
                   const lldb::BatonSP &baton_sp, bool synchronous = false);

  void SetCallback(BreakpointHitCallback callback,
                   const BreakpointOptions::CommandBatonSP &command_baton_sp,
                   bool synchronous = false);

  /// Returns the command line commands for the callback on this breakpoint.
  ///
  /// \param[out] command_list
  ///    The commands will be appended to this list.
  ///
  /// \return
  ///    \b true if the command callback is a command-line callback,
  ///    \b false otherwise.
  bool GetCommandLineCallbacks(StringList &command_list);

  /// Remove the callback from this option set.
  void ClearCallback();

  // The rest of these functions are meant to be used only within the
  // breakpoint handling mechanism.

  /// Use this function to invoke the callback for a specific stop.
  ///
  /// \param[in] context
  ///    The context in which the callback is to be invoked.  This includes the
  ///    stop event, the
  ///    execution context of the stop (since you might hit the same breakpoint
  ///    on multiple threads) and
  ///    whether we are currently executing synchronous or asynchronous
  ///    callbacks.
  ///
  /// \param[in] break_id
  ///    The breakpoint ID that owns this option set.
  ///
  /// \param[in] break_loc_id
  ///    The breakpoint location ID that owns this option set.
  ///
  /// \return
  ///     The callback return value.
  bool InvokeCallback(StoppointCallbackContext *context,
                      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);

  /// Used in InvokeCallback to tell whether it is the right time to run this
  /// kind of callback.
  ///
  /// \return
  ///     The synchronicity of our callback.
  bool IsCallbackSynchronous() const { return m_callback_is_synchronous; }

  /// Fetch the baton from the callback.
  ///
  /// \return
  ///     The baton.
  Baton *GetBaton();

  /// Fetch  a const version of the baton from the callback.
  ///
  /// \return
  ///     The baton.
  const Baton *GetBaton() const;

  // Condition
  /// Set the breakpoint option's condition.
  ///
  /// \param[in] condition
  ///    The condition expression to evaluate when the breakpoint is hit.
  void SetCondition(const char *condition);

  /// Return a pointer to the text of the condition expression.
  ///
  /// \return
  ///    A pointer to the condition expression text, or nullptr if no
  //     condition has been set.
  const char *GetConditionText(size_t *hash = nullptr) const;

  // Enabled/Ignore Count

  /// Check the Enable/Disable state.
  /// \return
  ///     \b true if the breakpoint is enabled, \b false if disabled.
  bool IsEnabled() const { return m_enabled; }

  /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
  void SetEnabled(bool enabled) {
    m_enabled = enabled;
    m_set_flags.Set(eEnabled);
  }

  /// Check the auto-continue state.
  /// \return
  ///     \b true if the breakpoint is set to auto-continue, \b false otherwise.
  bool IsAutoContinue() const { return m_auto_continue; }

  /// Set the auto-continue state.
  void SetAutoContinue(bool auto_continue) {
    m_auto_continue = auto_continue;
    m_set_flags.Set(eAutoContinue);
  }

  /// Check the One-shot state.
  /// \return
  ///     \b true if the breakpoint is one-shot, \b false otherwise.
  bool IsOneShot() const { return m_one_shot; }

  /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
  void SetOneShot(bool one_shot) {
    m_one_shot = one_shot;
    m_set_flags.Set(eOneShot);
  }

  /// Set the breakpoint to ignore the next \a count breakpoint hits.
  /// \param[in] n
  ///    The number of breakpoint hits to ignore.
  void SetIgnoreCount(uint32_t n) {
    m_ignore_count = n;
    m_set_flags.Set(eIgnoreCount);
  }

  /// Return the current Ignore Count.
  /// \return
  ///     The number of breakpoint hits to be ignored.
  uint32_t GetIgnoreCount() const { return m_ignore_count; }

  /// Return the current thread spec for this option. This will return nullptr
  /// if the no thread specifications have been set for this Option yet.
  /// \return
  ///     The thread specification pointer for this option, or nullptr if none
  ///     has
  ///     been set yet.
  const ThreadSpec *GetThreadSpecNoCreate() const;

  /// Returns a pointer to the ThreadSpec for this option, creating it. if it
  /// hasn't been created already.   This API is used for setting the
  /// ThreadSpec items for this option.
  ThreadSpec *GetThreadSpec();

  void SetThreadID(lldb::tid_t thread_id);

  void GetDescription(Stream *s, lldb::DescriptionLevel level) const;

  /// Check if the breakpoint option has a callback set.
  ///
  /// \return
  ///    If the breakpoint option has a callback, \b true otherwise \b false.
  bool HasCallback() const;

  /// This is the default empty callback.
  static bool NullCallback(void *baton, StoppointCallbackContext *context,
                           lldb::user_id_t break_id,
                           lldb::user_id_t break_loc_id);

  /// Set a callback based on BreakpointOptions::CommandData. \param[in]
  /// cmd_data
  ///     A UP holding the new'ed CommandData object.
  ///     The breakpoint will take ownership of pointer held by this object.
  void SetCommandDataCallback(std::unique_ptr<CommandData> &cmd_data);

  void Clear();

  bool AnySet() const {
    return m_set_flags.AnySet(eAllOptions);
  }

protected:
  // Classes that inherit from BreakpointOptions can see and modify these
  bool IsOptionSet(OptionKind kind)
  {
    return m_set_flags.Test(kind);
  }

  enum class OptionNames {
    ConditionText = 0,
    IgnoreCount,
    EnabledState,
    OneShotState,
    AutoContinue,
    LastOptionName
  };
  static const char *g_option_names[(size_t)OptionNames::LastOptionName];

  static const char *GetKey(OptionNames enum_value) {
    return g_option_names[(size_t)enum_value];
  }

  static bool BreakpointOptionsCallbackFunction(
      void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
      lldb::user_id_t break_loc_id);

  void SetThreadSpec(std::unique_ptr<ThreadSpec> &thread_spec_up);

private:
  /// For BreakpointOptions only

  /// This is the callback function pointer
  BreakpointHitCallback m_callback;
  /// This is the client data for the callback
  lldb::BatonSP m_callback_baton_sp;
  bool m_baton_is_command_baton;
  bool m_callback_is_synchronous;
  bool m_enabled;
  /// If set, the breakpoint delete itself after being hit once.
  bool m_one_shot;
  /// Number of times to ignore this breakpoint.
  uint32_t m_ignore_count;
  /// Thread for which this breakpoint will stop.
  std::unique_ptr<ThreadSpec> m_thread_spec_up;
  /// The condition to test.
  std::string m_condition_text;
  /// Its hash, so that locations know when the condition is updated.
  size_t m_condition_text_hash;
  /// If set, inject breakpoint condition into process.
  bool m_inject_condition;
  /// If set, auto-continue from breakpoint.
  bool m_auto_continue;
  /// Which options are set at this level.
  /// Drawn from BreakpointOptions::SetOptionsFlags.
  Flags m_set_flags;
};

} // namespace lldb_private

#endif // LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H
