#!/usr/bin/env python
##===-- lui.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 curses

import lldb
import lldbutil

from optparse import OptionParser
import os
import signal
import sys

try:
    import queue
except ImportError:
    import Queue as queue

import debuggerdriver
import cui

import breakwin
import commandwin
import eventwin
import sourcewin
import statuswin

event_queue = None


def handle_args(driver, argv):
    parser = OptionParser()
    parser.add_option(
        "-p",
        "--attach",
        dest="pid",
        help="Attach to specified Process ID",
        type="int")
    parser.add_option(
        "-c",
        "--core",
        dest="core",
        help="Load specified core file",
        type="string")

    (options, args) = parser.parse_args(argv)

    if options.pid is not None:
        try:
            pid = int(options.pid)
            driver.attachProcess(ui, pid)
        except ValueError:
            print("Error: expecting integer PID, got '%s'" % options.pid)
    elif options.core is not None:
        if not os.path.exists(options.core):
            raise Exception(
                "Specified core file '%s' does not exist." %
                options.core)
        driver.loadCore(options.core)
    elif len(args) == 2:
        if not os.path.isfile(args[1]):
            raise Exception("Specified target '%s' does not exist" % args[1])
        driver.createTarget(args[1])
    elif len(args) > 2:
        if not os.path.isfile(args[1]):
            raise Exception("Specified target '%s' does not exist" % args[1])
        driver.createTarget(args[1], args[2:])


def sigint_handler(signal, frame):
    global debugger
    debugger.terminate()


class LLDBUI(cui.CursesUI):

    def __init__(self, screen, event_queue, driver):
        super(LLDBUI, self).__init__(screen, event_queue)

        self.driver = driver

        h, w = self.screen.getmaxyx()

        command_win_height = 20
        break_win_width = 60

        self.status_win = statuswin.StatusWin(0, h - 1, w, 1)
        h -= 1
        self.command_win = commandwin.CommandWin(
            driver, 0, h - command_win_height, w, command_win_height)
        h -= command_win_height
        self.source_win = sourcewin.SourceWin(driver, 0, 0,
                                              w - break_win_width - 1, h)
        self.break_win = breakwin.BreakWin(driver, w - break_win_width, 0,
                                           break_win_width, h)

        self.wins = [self.status_win,
                     # self.event_win,
                     self.source_win,
                     self.break_win,
                     self.command_win,
                     ]

        self.focus = len(self.wins) - 1  # index of command window;

    def handleEvent(self, event):
        # hack
        if isinstance(event, int):
            if event == curses.KEY_F10:
                self.driver.terminate()
            if event == 20:  # ctrl-T
                def foo(cmd):
                    ret = lldb.SBCommandReturnObject()
                    self.driver.getCommandInterpreter().HandleCommand(cmd, ret)
                foo('target create a.out')
                foo('b main')
                foo('run')
        super(LLDBUI, self).handleEvent(event)


def main(screen):
    signal.signal(signal.SIGINT, sigint_handler)

    global event_queue
    event_queue = queue.Queue()

    global debugger
    debugger = lldb.SBDebugger.Create()

    driver = debuggerdriver.createDriver(debugger, event_queue)
    view = LLDBUI(screen, event_queue, driver)

    driver.start()

    # hack to avoid hanging waiting for prompts!
    driver.handleCommand("settings set auto-confirm true")

    handle_args(driver, sys.argv)
    view.eventLoop()

if __name__ == "__main__":
    try:
        curses.wrapper(main)
    except KeyboardInterrupt:
        exit()
