# Path: debugger/debugee.py
# class Breakpoint(object):
#     """
#     Represents a breakpoint.
#     """
#     def __init__(self, number, location, line):
#         """
#         @type number: int
#         @type location: str
#         @type line: int
#         """
#         self.number = number
#         self.location = location
#         self.line = line
# 
#     def __repr__(self):
#         return "BP #{0}: {1}:{2}".format(self.number, self.location, self.line)
# 
# Path: debugger/enums.py
# class DebuggerState(Enum):
#     """
#     Represents debugger state.
#     """
#     Started = 1
#     BinaryLoaded = 2
#     Running = 3
# 
# Path: debugger/debugger_api.py
# class ProcessExitedEventData(object):
# class ProcessStoppedEventData(object):
# class StartupInfo(object):
# class HeapManager(object):
# class IOManager(object):
# class BreakpointManager(object):
# class FileManager(object):
# class ThreadManager(object):
# class VariableManager(object):
# class Debugger(object):
#     def __init__(self, return_code):
#     def __init__(self, stop_reason):
#     def __init__(self, cmd_arguments="", working_directory="", env_vars=None):
#     def copy(self):
#     def __repr__(self):
#     def __init__(self, debugger):
#     def watch(self):
#     def stop(self):
#     def find_block_by_address(self, addr):
#     def get_total_allocations(self):
#     def get_total_deallocations(self):
#     def __init__(self):
#     def handle_io(self):
#     def stop_io(self):
#     def __init__(self, debugger):
#     def add_breakpoint(self, location, line):
#     def toggle_breakpoint(self, location, line):
#     def get_breakpoints(self):
#     def find_breakpoint(self, location, line):
#     def remove_breakpoint(self, location, line):
#     def __init__(self, debugger):
#     def get_main_source_file(self):
#     def get_current_location(self):
#     def get_line_address(self, filename, line):
#     def disassemble(self, filename, line):
#     def disassemble_raw(self, filename, line):
#     def __init__(self, debugger):
#     def get_current_thread(self):
#     def get_thread_info(self):
#     def set_thread_by_index(self, thread_id):
#     def get_current_frame(self, with_variables=False):
#     def get_frames(self):
#     def get_frames_with_variables(self):
#     def change_frame(self, frame_index):
#     def __init__(self, debugger):
#     def get_type(self, expression, level=0):
#     def get_variable(self, expression, level=0):
#     def update_variable(self, variable):
#     def get_memory(self, address, count):
#     def get_registers(self):
#     def get_vector_items(self, vector):
#     def __init__(self):
#     def require_state(self, required_state):
#     def get_state(self):
#     def get_process_state(self):
#     def load_binary(self, binary_path):
#     def launch(self, startup_info=None):
#     def exec_continue(self):
#     def exec_pause(self):
#     def exec_step_over(self):
#     def exec_step_in(self):
#     def exec_step_out(self):
#     def quit_program(self, return_code=1):
#     def terminate(self):
#     def wait_for_stop(self):
#     def wait_for_exit(self):


import os
from debugger.debugee import Breakpoint
from debugger.enums import DebuggerState
from debugger import debugger_api




class LldbBreakpointManager(debugger_api.BreakpointManager):
    def __init__(self, debugger):
        super(LldbBreakpointManager, self).__init__(debugger)

    def get_breakpoints(self):
        bps = [self.debugger.target.GetBreakpointAtIndex(i)
               for i in xrange(self.debugger.target.GetNumBreakpoints())]
        breakpoints = []
        for bp in bps:
            if bp.num_locations > 0:
                location = bp.GetLocationAtIndex(0)
                address = location.GetAddress().line_entry
                line = address.line
                file = os.path.abspath(address.file.fullpath)
                breakpoints.append(Breakpoint(bp.id, file, line))

        return breakpoints

    def toggle_breakpoint(self, location, line):
        bp = self.find_breakpoint(location, line)
        if bp:
            return self.remove_breakpoint(location, line)
        else:
            return self.add_breakpoint(location, line)

    def add_breakpoint(self, location, line):

# Path: debugger/debugee.py
# class Breakpoint(object):
#     """
#     Represents a breakpoint.
#     """
#     def __init__(self, number, location, line):
#         """
#         @type number: int
#         @type location: str
#         @type line: int
#         """
#         self.number = number
#         self.location = location
#         self.line = line
# 
#     def __repr__(self):
#         return "BP #{0}: {1}:{2}".format(self.number, self.location, self.line)
# 
# Path: debugger/enums.py
# class DebuggerState(Enum):
#     """
#     Represents debugger state.
#     """
#     Started = 1
#     BinaryLoaded = 2
#     Running = 3
# 
# Path: debugger/debugger_api.py
# class ProcessExitedEventData(object):
# class ProcessStoppedEventData(object):
# class StartupInfo(object):
# class HeapManager(object):
# class IOManager(object):
# class BreakpointManager(object):
# class FileManager(object):
# class ThreadManager(object):
# class VariableManager(object):
# class Debugger(object):
#     def __init__(self, return_code):
#     def __init__(self, stop_reason):
#     def __init__(self, cmd_arguments="", working_directory="", env_vars=None):
#     def copy(self):
#     def __repr__(self):
#     def __init__(self, debugger):
#     def watch(self):
#     def stop(self):
#     def find_block_by_address(self, addr):
#     def get_total_allocations(self):
#     def get_total_deallocations(self):
#     def __init__(self):
#     def handle_io(self):
#     def stop_io(self):
#     def __init__(self, debugger):
#     def add_breakpoint(self, location, line):
#     def toggle_breakpoint(self, location, line):
#     def get_breakpoints(self):
#     def find_breakpoint(self, location, line):
#     def remove_breakpoint(self, location, line):
#     def __init__(self, debugger):
#     def get_main_source_file(self):
#     def get_current_location(self):
#     def get_line_address(self, filename, line):
#     def disassemble(self, filename, line):
#     def disassemble_raw(self, filename, line):
#     def __init__(self, debugger):
#     def get_current_thread(self):
#     def get_thread_info(self):
#     def set_thread_by_index(self, thread_id):
#     def get_current_frame(self, with_variables=False):
#     def get_frames(self):
#     def get_frames_with_variables(self):
#     def change_frame(self, frame_index):
#     def __init__(self, debugger):
#     def get_type(self, expression, level=0):
#     def get_variable(self, expression, level=0):
#     def update_variable(self, variable):
#     def get_memory(self, address, count):
#     def get_registers(self):
#     def get_vector_items(self, vector):
#     def __init__(self):
#     def require_state(self, required_state):
#     def get_state(self):
#     def get_process_state(self):
#     def load_binary(self, binary_path):
#     def launch(self, startup_info=None):
#     def exec_continue(self):
#     def exec_pause(self):
#     def exec_step_over(self):
#     def exec_step_in(self):
#     def exec_step_out(self):
#     def quit_program(self, return_code=1):
#     def terminate(self):
#     def wait_for_stop(self):
#     def wait_for_exit(self):


# Path: debugger/lldbc/lldb_breakpoint_manager.py
import os
from debugger.debugee import Breakpoint
from debugger.enums import DebuggerState
from debugger import debugger_api





class LldbBreakpointManager(debugger_api.BreakpointManager):
    def __init__(self, debugger):
        super(LldbBreakpointManager, self).__init__(debugger)

    def get_breakpoints(self):
        bps = [self.debugger.target.GetBreakpointAtIndex(i)
               for i in xrange(self.debugger.target.GetNumBreakpoints())]
        breakpoints = []
        for bp in bps:
            if bp.num_locations > 0:
                location = bp.GetLocationAtIndex(0)
                address = location.GetAddress().line_entry
                line = address.line
                file = os.path.abspath(address.file.fullpath)
                breakpoints.append(Breakpoint(bp.id, file, line))

        return breakpoints

    def toggle_breakpoint(self, location, line):
        bp = self.find_breakpoint(location, line)
        if bp:
            return self.remove_breakpoint(location, line)
        else:
            return self.add_breakpoint(location, line)

    def add_breakpoint(self, location, line):

        self.debugger.require_state(DebuggerState.BinaryLoaded)