#!/usr/bin/env python3
"""
A gdb-compatible frontend for lldb that implements just enough
commands to run the tests in the debuginfo-tests repository with lldb.
"""

# ----------------------------------------------------------------------
# Auto-detect lldb python module.
import subprocess, platform, os, sys

# Set the path to look first for the built lldb (in case it exists).
lldb_python_path = os.environ["LLDB_PYTHON_PATH"]
if len(lldb_python_path) > 0:
    sys.path.insert(0, lldb_python_path)

try:
    # Just try for LLDB in case PYTHONPATH is already correctly setup.
    import lldb
except ImportError:
    # Ask the command line driver for the path to the lldb module. Copy over
    # the environment so that SDKROOT is propagated to xcrun.
    command = (
        ["xcrun", "lldb", "-P"] if platform.system() == "Darwin" else ["lldb", "-P"]
    )
    # Extend the PYTHONPATH if the path exists and isn't already there.
    lldb_python_path = subprocess.check_output(command).decode("utf-8").strip()
    if os.path.exists(lldb_python_path) and not sys.path.__contains__(lldb_python_path):
        sys.path.append(lldb_python_path)
    # Try importing LLDB again.
    try:
        import lldb

        print('imported lldb from: "%s"' % lldb_python_path)
    except ImportError:
        print(
            "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
        )
        sys.exit(1)
# ----------------------------------------------------------------------

# Command line option handling.
import argparse

parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--quiet", "-q", action="store_true", help="ignored")
parser.add_argument(
    "-batch", action="store_true", help="exit after processing comand line"
)
parser.add_argument("-n", action="store_true", help="ignore .lldb file")
parser.add_argument(
    "-x", dest="script", type=argparse.FileType("r"), help="execute commands from file"
)
parser.add_argument("target", help="the program to debug")
args = parser.parse_args()


# Create a new debugger instance.
debugger = lldb.SBDebugger.Create()
debugger.SkipLLDBInitFiles(args.n)

# Make sure to clean up the debugger on exit.
import atexit


def on_exit():
    debugger.Terminate()


atexit.register(on_exit)

# Don't return from lldb function calls until the process stops.
debugger.SetAsync(False)

# Create a target from a file and arch.
arch = os.popen("file " + args.target).read().split()[-1]
target = debugger.CreateTargetWithFileAndArch(args.target, arch)

if not target:
    print("Could not create target %s" % args.target)
    sys.exit(1)

if not args.script:
    print("Interactive mode is not implemented.")
    sys.exit(1)

import re

for command in args.script:
    # Strip newline and whitespaces and split into words.
    cmd = command[:-1].strip().split()
    if not cmd:
        continue

    print("> %s" % command[:-1])

    try:
        if re.match("^r|(run)$", cmd[0]):
            error = lldb.SBError()
            launchinfo = lldb.SBLaunchInfo([])
            launchinfo.SetWorkingDirectory(os.getcwd())
            process = target.Launch(launchinfo, error)
            print(error)
            if not process or error.fail:
                state = process.GetState()
                print("State = %d" % state)
                print(
                    """
ERROR: Could not launch process.
NOTE: There are several reasons why this may happen:
  * Root needs to run "DevToolsSecurity --enable".
  * Older versions of lldb cannot launch more than one process simultaneously.
"""
                )
                sys.exit(1)

        elif re.match("^b|(break)$", cmd[0]) and len(cmd) == 2:
            if re.match("[0-9]+", cmd[1]):
                # b line
                mainfile = target.FindFunctions("main")[0].compile_unit.file
                print(target.BreakpointCreateByLocation(mainfile, int(cmd[1])))
            else:
                # b file:line
                file, line = cmd[1].split(":")
                print(target.BreakpointCreateByLocation(file, int(line)))

        elif re.match("^ptype$", cmd[0]) and len(cmd) == 2:
            # GDB's ptype has multiple incarnations depending on its
            # argument (global variable, function, type).  The definition
            # here is for looking up the signature of a function and only
            # if that fails it looks for a type with that name.
            # Type lookup in LLDB would be "image lookup --type".
            for elem in target.FindFunctions(cmd[1]):
                print(elem.function.type)
                continue
            print(target.FindFirstType(cmd[1]))

        elif re.match("^po$", cmd[0]) and len(cmd) > 1:
            try:
                opts = lldb.SBExpressionOptions()
                opts.SetFetchDynamicValue(True)
                opts.SetCoerceResultToId(True)
                print(target.EvaluateExpression(" ".join(cmd[1:]), opts))
            except:
                # FIXME: This is a fallback path for the lab.llvm.org
                # buildbot running OS X 10.7; it should be removed.
                thread = process.GetThreadAtIndex(0)
                frame = thread.GetFrameAtIndex(0)
                print(frame.EvaluateExpression(" ".join(cmd[1:])))

        elif re.match("^p|(print)$", cmd[0]) and len(cmd) > 1:
            thread = process.GetThreadAtIndex(0)
            frame = thread.GetFrameAtIndex(0)
            print(frame.EvaluateExpression(" ".join(cmd[1:])))

        elif re.match("^n|(next)$", cmd[0]):
            thread = process.GetThreadAtIndex(0)
            thread.StepOver()

        elif re.match("^q|(quit)$", cmd[0]):
            sys.exit(0)

        else:
            print(debugger.HandleCommand(" ".join(cmd)))

    except SystemExit:
        raise
    except:
        print('Could not handle the command "%s"' % " ".join(cmd))
