//===-- SWIG Interface for SBBreakpoint -------------------------*- 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
//
//===----------------------------------------------------------------------===//
namespace lldb {

%feature("docstring",
"Represents a logical breakpoint and its associated settings.

For example (from test/functionalities/breakpoint/breakpoint_ignore_count/
TestBreakpointIgnoreCount.py),

    def breakpoint_ignore_count_python(self):
        '''Use Python APIs to set breakpoint ignore count.'''
        exe = os.path.join(os.getcwd(), 'a.out')

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Now create a breakpoint on main.c by name 'c'.
        breakpoint = target.BreakpointCreateByName('c', 'a.out')
        self.assertTrue(breakpoint and
                        breakpoint.GetNumLocations() == 1,
                        VALID_BREAKPOINT)

        # Get the breakpoint location from breakpoint after we verified that,
        # indeed, it has one location.
        location = breakpoint.GetLocationAtIndex(0)
        self.assertTrue(location and
                        location.IsEnabled(),
                        VALID_BREAKPOINT_LOCATION)

        # Set the ignore count on the breakpoint location.
        location.SetIgnoreCount(2)
        self.assertTrue(location.GetIgnoreCount() == 2,
                        'SetIgnoreCount() works correctly')

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None, os.getcwd())
        self.assertTrue(process, PROCESS_IS_VALID)

        # Frame#0 should be on main.c:37, frame#1 should be on main.c:25, and
        # frame#2 should be on main.c:48.
        #lldbutil.print_stacktraces(process)
        from lldbutil import get_stopped_thread
        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        self.assertTrue(thread != None, 'There should be a thread stopped due to breakpoint')
        frame0 = thread.GetFrameAtIndex(0)
        frame1 = thread.GetFrameAtIndex(1)
        frame2 = thread.GetFrameAtIndex(2)
        self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and
                        frame1.GetLineEntry().GetLine() == self.line3 and
                        frame2.GetLineEntry().GetLine() == self.line4,
                        STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT)

        # The hit count for the breakpoint should be 3.
        self.assertTrue(breakpoint.GetHitCount() == 3)

        process.Continue()

SBBreakpoint supports breakpoint location iteration, for example,

    for bl in breakpoint:
        print('breakpoint location load addr: %s' % hex(bl.GetLoadAddress()))
        print('breakpoint location condition: %s' % hex(bl.GetCondition()))

and rich comparison methods which allow the API program to use,

    if aBreakpoint == bBreakpoint:
        ...

to compare two breakpoints for equality."
) SBBreakpoint;
class SBBreakpoint
{
public:

    SBBreakpoint ();

    SBBreakpoint (const lldb::SBBreakpoint& rhs);

    ~SBBreakpoint();

    bool operator==(const lldb::SBBreakpoint &rhs);

    bool operator!=(const lldb::SBBreakpoint &rhs);

    break_id_t
    GetID () const;

    bool
    IsValid() const;

    explicit operator bool() const;

    void
    ClearAllBreakpointSites ();

    lldb::SBBreakpointLocation
    FindLocationByAddress (lldb::addr_t vm_addr);

    lldb::break_id_t
    FindLocationIDByAddress (lldb::addr_t vm_addr);

    lldb::SBBreakpointLocation
    FindLocationByID (lldb::break_id_t bp_loc_id);

    lldb::SBBreakpointLocation
    GetLocationAtIndex (uint32_t index);

    void
    SetEnabled (bool enable);

    bool
    IsEnabled ();

    void
    SetOneShot (bool one_shot);

    bool
    IsOneShot ();

    bool
    IsInternal ();

    uint32_t
    GetHitCount () const;

    void
    SetIgnoreCount (uint32_t count);

    uint32_t
    GetIgnoreCount () const;

    %feature("docstring", "
    The breakpoint stops only if the condition expression evaluates to true.") SetCondition;
    void
    SetCondition (const char *condition);

    %feature("docstring", "
    Get the condition expression for the breakpoint.") GetCondition;
    const char *
    GetCondition ();

    void SetAutoContinue(bool auto_continue);

    bool GetAutoContinue();

    void
    SetThreadID (lldb::tid_t sb_thread_id);

    lldb::tid_t
    GetThreadID ();

    void
    SetThreadIndex (uint32_t index);

    uint32_t
    GetThreadIndex() const;

    void
    SetThreadName (const char *thread_name);

    const char *
    GetThreadName () const;

    void
    SetQueueName (const char *queue_name);

    const char *
    GetQueueName () const;

    %feature("docstring", "
    Set the name of the script function to be called when the breakpoint is hit.") SetScriptCallbackFunction;
    void
    SetScriptCallbackFunction (const char *callback_function_name);

    %feature("docstring", "
    Set the name of the script function to be called when the breakpoint is hit.
    To use this variant, the function should take (frame, bp_loc, extra_args, dict) and
    when the breakpoint is hit the extra_args will be passed to the callback function.") SetScriptCallbackFunction;
    SBError
    SetScriptCallbackFunction (const char *callback_function_name,
                               SBStructuredData &extra_args);

    %feature("docstring", "
    Provide the body for the script function to be called when the breakpoint is hit.
    The body will be wrapped in a function, which be passed two arguments:
    'frame' - which holds the bottom-most SBFrame of the thread that hit the breakpoint
    'bpno'  - which is the SBBreakpointLocation to which the callback was attached.

    The error parameter is currently ignored, but will at some point hold the Python
    compilation diagnostics.
    Returns true if the body compiles successfully, false if not.") SetScriptCallbackBody;
    SBError
    SetScriptCallbackBody (const char *script_body_text);

    void SetCommandLineCommands(SBStringList &commands);

    bool GetCommandLineCommands(SBStringList &commands);

    bool
    AddName (const char *new_name);

    SBError
    AddNameWithErrorHandling (const char *new_name);

    void
    RemoveName (const char *name_to_remove);

    bool
    MatchesName (const char *name);

    void
    GetNames (SBStringList &names);

    size_t
    GetNumResolvedLocations() const;

    size_t
    GetNumLocations() const;

    bool
    GetDescription (lldb::SBStream &description);

    bool
    GetDescription(lldb::SBStream &description, bool include_locations);

    // Can only be called from a ScriptedBreakpointResolver...
    SBError
    AddLocation(SBAddress &address);

    static bool
    EventIsBreakpointEvent (const lldb::SBEvent &event);

    static lldb::BreakpointEventType
    GetBreakpointEventTypeFromEvent (const lldb::SBEvent& event);

    static lldb::SBBreakpoint
    GetBreakpointFromEvent (const lldb::SBEvent& event);

    static lldb::SBBreakpointLocation
    GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx);

    static uint32_t
    GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event_sp);

    bool
    IsHardware ();

    STRING_EXTENSION(SBBreakpoint)

#ifdef SWIGPYTHON
    %pythoncode %{

        class locations_access(object):
            '''A helper object that will lazily hand out locations for a breakpoint when supplied an index.'''
            def __init__(self, sbbreakpoint):
                self.sbbreakpoint = sbbreakpoint

            def __len__(self):
                if self.sbbreakpoint:
                    return int(self.sbbreakpoint.GetNumLocations())
                return 0

            def __getitem__(self, key):
                if type(key) is int and key < len(self):
                    return self.sbbreakpoint.GetLocationAtIndex(key)
                return None

        def get_locations_access_object(self):
            '''An accessor function that returns a locations_access() object which allows lazy location access from a lldb.SBBreakpoint object.'''
            return self.locations_access (self)

        def get_breakpoint_location_list(self):
            '''An accessor function that returns a list() that contains all locations in a lldb.SBBreakpoint object.'''
            locations = []
            accessor = self.get_locations_access_object()
            for idx in range(len(accessor)):
                locations.append(accessor[idx])
            return locations

        def __iter__(self):
            '''Iterate over all breakpoint locations in a lldb.SBBreakpoint
            object.'''
            return lldb_iter(self, 'GetNumLocations', 'GetLocationAtIndex')

        def __len__(self):
            '''Return the number of breakpoint locations in a lldb.SBBreakpoint
            object.'''
            return self.GetNumLocations()

        locations = property(get_breakpoint_location_list, None, doc='''A read only property that returns a list() of lldb.SBBreakpointLocation objects for this breakpoint.''')
        location = property(get_locations_access_object, None, doc='''A read only property that returns an object that can access locations by index (not location ID) (location = bkpt.location[12]).''')
        id = property(GetID, None, doc='''A read only property that returns the ID of this breakpoint.''')
        enabled = property(IsEnabled, SetEnabled, doc='''A read/write property that configures whether this breakpoint is enabled or not.''')
        one_shot = property(IsOneShot, SetOneShot, doc='''A read/write property that configures whether this breakpoint is one-shot (deleted when hit) or not.''')
        num_locations = property(GetNumLocations, None, doc='''A read only property that returns the count of locations of this breakpoint.''')
    %}
#endif


};

class SBBreakpointListImpl;

class LLDB_API SBBreakpointList
{
public:
  SBBreakpointList(SBTarget &target);

  ~SBBreakpointList();

  size_t GetSize() const;

  SBBreakpoint
  GetBreakpointAtIndex(size_t idx);

  SBBreakpoint
  FindBreakpointByID(lldb::break_id_t);

  void Append(const SBBreakpoint &sb_bkpt);

  bool AppendIfUnique(const SBBreakpoint &sb_bkpt);

  void AppendByID (lldb::break_id_t id);

  void Clear();
private:
  std::shared_ptr<SBBreakpointListImpl> m_opaque_sp;
};

} // namespace lldb
