##===-- debuggerdriver.py ------------------------------------*- Python -*-===##
##
# 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
##
##===----------------------------------------------------------------------===##


import lldb
import lldbutil
import sys
from threading import Thread


class DebuggerDriver(Thread):
    """ Drives the debugger and responds to events. """

    def __init__(self, debugger, event_queue):
        Thread.__init__(self)
        self.event_queue = event_queue
        # This is probably not great because it does not give liblldb a chance
        # to clean up
        self.daemon = True
        self.initialize(debugger)

    def initialize(self, debugger):
        self.done = False
        self.debugger = debugger
        self.listener = debugger.GetListener()
        if not self.listener.IsValid():
            raise "Invalid listener"

        self.listener.StartListeningForEventClass(self.debugger,
                                                  lldb.SBTarget.GetBroadcasterClassName(),
                                                  lldb.SBTarget.eBroadcastBitBreakpointChanged
                                                  #| lldb.SBTarget.eBroadcastBitModuleLoaded
                                                  #| lldb.SBTarget.eBroadcastBitModuleUnloaded
                                                  | lldb.SBTarget.eBroadcastBitWatchpointChanged
                                                  #| lldb.SBTarget.eBroadcastBitSymbolLoaded
                                                  )

        self.listener.StartListeningForEventClass(self.debugger,
                                                  lldb.SBThread.GetBroadcasterClassName(),
                                                  lldb.SBThread.eBroadcastBitStackChanged
                                                  #  lldb.SBThread.eBroadcastBitBreakpointChanged
                                                  | lldb.SBThread.eBroadcastBitThreadSuspended
                                                  | lldb.SBThread.eBroadcastBitThreadResumed
                                                  | lldb.SBThread.eBroadcastBitSelectedFrameChanged
                                                  | lldb.SBThread.eBroadcastBitThreadSelected
                                                  )

        self.listener.StartListeningForEventClass(self.debugger,
                                                  lldb.SBProcess.GetBroadcasterClassName(),
                                                  lldb.SBProcess.eBroadcastBitStateChanged
                                                  | lldb.SBProcess.eBroadcastBitInterrupt
                                                  | lldb.SBProcess.eBroadcastBitSTDOUT
                                                  | lldb.SBProcess.eBroadcastBitSTDERR
                                                  | lldb.SBProcess.eBroadcastBitProfileData
                                                  )
        self.listener.StartListeningForEventClass(self.debugger,
                                                  lldb.SBCommandInterpreter.GetBroadcasterClass(),
                                                  lldb.SBCommandInterpreter.eBroadcastBitThreadShouldExit
                                                  | lldb.SBCommandInterpreter.eBroadcastBitResetPrompt
                                                  | lldb.SBCommandInterpreter.eBroadcastBitQuitCommandReceived
                                                  | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousOutputData
                                                  | lldb.SBCommandInterpreter.eBroadcastBitAsynchronousErrorData
                                                  )

    def createTarget(self, target_image, args=None):
        self.handleCommand("target create %s" % target_image)
        if args is not None:
            self.handleCommand("settings set target.run-args %s" % args)

    def attachProcess(self, pid):
        self.handleCommand("process attach -p %d" % pid)
        pass

    def loadCore(self, corefile):
        self.handleCommand("target create -c %s" % corefile)
        pass

    def setDone(self):
        self.done = True

    def isDone(self):
        return self.done

    def getPrompt(self):
        return self.debugger.GetPrompt()

    def getCommandInterpreter(self):
        return self.debugger.GetCommandInterpreter()

    def getSourceManager(self):
        return self.debugger.GetSourceManager()

    def setSize(self, width, height):
        # FIXME: respect height
        self.debugger.SetTerminalWidth(width)

    def getTarget(self):
        return self.debugger.GetTargetAtIndex(0)

    def handleCommand(self, cmd):
        ret = lldb.SBCommandReturnObject()
        self.getCommandInterpreter().HandleCommand(cmd, ret)
        return ret

    def eventLoop(self):
        while not self.isDone():
            event = lldb.SBEvent()
            got_event = self.listener.WaitForEvent(lldb.UINT32_MAX, event)
            if got_event and not event.IsValid():
                self.winAddStr("Warning: Invalid or no event...")
                continue
            elif not event.GetBroadcaster().IsValid():
                continue

            self.event_queue.put(event)

    def run(self):
        self.eventLoop()

    def terminate(self):
        lldb.SBDebugger.Terminate()
        sys.exit(0)


def createDriver(debugger, event_queue):
    driver = DebuggerDriver(debugger, event_queue)
    # driver.start()
    # if pid specified:
    # - attach to pid
    # else if core file specified
    # - create target from corefile
    # else
    # - create target from file
    # - settings append target.run-args <args-from-cmdline>
    # source .lldbinit file

    return driver
