//===-- 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() = default;

    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
