from __future__ import print_function

import lldb
import re


def parse_linespec(linespec, frame, result):
    """Handles a subset of GDB-style linespecs.  Specifically:

       number           - A line in the current file
       +offset          - The line /offset/ lines after this line
       -offset          - The line /offset/ lines before this line
       filename:number  - Line /number/ in file /filename/
       function         - The start of /function/
       *address         - The pointer target of /address/, which must be a literal (but see `` in LLDB)

       We explicitly do not handle filename:function because it is ambiguous in Objective-C.

       This function returns a list of addresses."""

    breakpoint = None
    target = frame.GetThread().GetProcess().GetTarget()

    matched = False

    if (not matched):
        mo = re.match("^([0-9]+)$", linespec)
        if (mo is not None):
            matched = True
            # print "Matched <linenum>"
            line_number = int(mo.group(1))
            line_entry = frame.GetLineEntry()
            if not line_entry.IsValid():
                result.AppendMessage(
                    "Specified a line in the current file, but the current frame doesn't have line table information.")
                return
            breakpoint = target.BreakpointCreateByLocation(
                line_entry.GetFileSpec(), line_number)

    if (not matched):
        mo = re.match("^\+([0-9]+)$", linespec)
        if (mo is not None):
            matched = True
            # print "Matched +<count>"
            line_number = int(mo.group(1))
            line_entry = frame.GetLineEntry()
            if not line_entry.IsValid():
                result.AppendMessage(
                    "Specified a line in the current file, but the current frame doesn't have line table information.")
                return
            breakpoint = target.BreakpointCreateByLocation(
                line_entry.GetFileSpec(), (line_entry.GetLine() + line_number))

    if (not matched):
        mo = re.match("^\-([0-9]+)$", linespec)
        if (mo is not None):
            matched = True
            # print "Matched -<count>"
            line_number = int(mo.group(1))
            line_entry = frame.GetLineEntry()
            if not line_entry.IsValid():
                result.AppendMessage(
                    "Specified a line in the current file, but the current frame doesn't have line table information.")
                return
            breakpoint = target.BreakpointCreateByLocation(
                line_entry.GetFileSpec(), (line_entry.GetLine() - line_number))

    if (not matched):
        mo = re.match("^(.*):([0-9]+)$", linespec)
        if (mo is not None):
            matched = True
            # print "Matched <filename>:<linenum>"
            file_name = mo.group(1)
            line_number = int(mo.group(2))
            breakpoint = target.BreakpointCreateByLocation(
                file_name, line_number)

    if (not matched):
        mo = re.match("\*((0x)?([0-9a-f]+))$", linespec)
        if (mo is not None):
            matched = True
            # print "Matched <address-expression>"
            address = int(mo.group(1), base=0)
            breakpoint = target.BreakpointCreateByAddress(address)

    if (not matched):
        # print "Trying <function-name>"
        breakpoint = target.BreakpointCreateByName(linespec)

    num_locations = breakpoint.GetNumLocations()

    if (num_locations == 0):
        result.AppendMessage(
            "The line specification provided doesn't resolve to any addresses.")

    addr_list = []

    for location_index in range(num_locations):
        location = breakpoint.GetLocationAtIndex(location_index)
        addr_list.append(location.GetAddress())

    target.BreakpointDelete(breakpoint.GetID())

    return addr_list


def usage_string():
    return """   Sets the program counter to a specific address.

Syntax: jump <linespec> [<location-id>]

Command Options Usage:
  jump <linenum>
  jump +<count>
  jump -<count>
  jump <filename>:<linenum>
  jump <function-name>
  jump *<address-expression>

<location-id> serves to disambiguate when multiple locations could be meant."""


def jump(debugger, command, result, internal_dict):
    if (command == ""):
        result.AppendMessage(usage_string())

    args = command.split()

    if not debugger.IsValid():
        result.AppendMessage("Invalid debugger!")
        return

    target = debugger.GetSelectedTarget()
    if not target.IsValid():
        result.AppendMessage("jump requires a valid target.")
        return

    process = target.GetProcess()
    if not process.IsValid():
        result.AppendMessage("jump requires a valid process.")
        return

    thread = process.GetSelectedThread()
    if not thread.IsValid():
        result.AppendMessage("jump requires a valid thread.")
        return

    frame = thread.GetSelectedFrame()
    if not frame.IsValid():
        result.AppendMessage("jump requires a valid frame.")
        return

    addresses = parse_linespec(args[0], frame, result)

    stream = lldb.SBStream()

    if len(addresses) == 0:
        return

    desired_address = addresses[0]

    if len(addresses) > 1:
        if len(args) == 2:
            desired_index = int(args[1])
            if (desired_index >= 0) and (desired_index < len(addresses)):
                desired_address = addresses[desired_index]
            else:
                result.AppendMessage(
                    "Desired index " +
                    args[1] +
                    " is not one of the options.")
                return
        else:
            index = 0
            result.AppendMessage(
                "The specified location resolves to multiple targets.")
            for address in addresses:
                stream.Clear()
                address.GetDescription(stream)
                result.AppendMessage(
                    "  Location ID " +
                    str(index) +
                    ": " +
                    stream.GetData())
                index = index + 1
            result.AppendMessage(
                "Please type 'jump " +
                command +
                " <location-id>' to choose one.")
            return

    frame.SetPC(desired_address.GetLoadAddress(target))

if lldb.debugger:
    # Module is being run inside the LLDB interpreter
    jump.__doc__ = usage_string()
    lldb.debugger.HandleCommand('command script add -f jump.jump jump')
    print('The "jump" command has been installed, type "help jump" or "jump <ENTER>" for detailed help.')
