module PryByebug::Breakpoints

def add_file(file, line, expression = nil)

Add file breakpoint.
def add_file(file, line, expression = nil)
  real_file = (file != Pry.eval_path)
  raise ArgumentError, 'Invalid file!' if real_file && !File.exist?(file)
  validate_expression expression
  Pry.processor.debugging = true
  path = (real_file ? File.expand_path(file) : file)
  bp = FileBreakpoint.new Byebug.add_breakpoint(path, line, expression)
  breakpoints << bp
  bp
end

def add_method(method, expression = nil)

Add method breakpoint.
def add_method(method, expression = nil)
  validate_expression expression
  Pry.processor.debugging = true
  owner, name = method.split /[\.#]/
  byebug_bp = Byebug.add_breakpoint(owner, name.to_sym, expression)
  bp = MethodBreakpoint.new byebug_bp, method
  breakpoints << bp
  bp
end

def breakpoints

def breakpoints
  @breakpoints ||= []
end

def change(id, expression = nil)

Change the conditional expression for a breakpoint.
def change(id, expression = nil)
  validate_expression expression
  breakpoint = find_by_id(id)
  breakpoint.expr = expression
  breakpoint
end

def change_status(id, enabled = true)

def change_status(id, enabled = true)
  breakpoint = find_by_id(id)
  breakpoint.enabled = enabled
  breakpoint
end

def clear

Delete all breakpoints.
def clear
  @breakpoints = []
  Byebug.breakpoints.clear if Byebug.started?
  Pry.processor.debugging = false
end

def delete(id)

Delete an existing breakpoint with the given ID.
def delete(id)
  deleted = Byebug.started? && 
    Byebug.remove_breakpoint(id) &&
    breakpoints.delete(find_by_id(id))
  raise ArgumentError, "No breakpoint ##{id}" if not deleted
  Pry.processor.debugging = false if to_a.empty?
end

def disable(id)

Disable a breakpoint with the given ID.
def disable(id)
  change_status id, false
end

def disable_all

Disable all breakpoints.
def disable_all
  each do |breakpoint|
    breakpoint.enabled = false
  end
end

def each(&block)

def each(&block)
  to_a.each(&block)
end

def enable(id)

Enable a disabled breakpoint with the given ID.
def enable(id)
  change_status id, true
end

def find_by_id(id)

def find_by_id(id)
  breakpoint = find { |b| b.id == id }
  raise ArgumentError, "No breakpoint ##{id}!" unless breakpoint
  breakpoint
end

def size

def size
  to_a.size
end

def to_a

def to_a
  breakpoints
end

def validate_expression(expression)

def validate_expression(expression)
  if expression &&   # `nil` implies no expression given, so pass
      (expression.empty? || !Pry::Code.complete_expression?(expression))
    raise "Invalid breakpoint conditional: #{expression}"
  end
end