//===-- 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()
        : user_source(), script_source(),
          interpreter(lldb::eScriptLanguageNone), stop_on_error(true) {}

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

    ~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; // eScriptLanguageNone means command interpreter.
    bool stop_on_error;

  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
  ///    \btrue if the command callback is a command-line callback,
  ///    \bfalse 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
