#!/usr/bin/env python
##===-- lui.py -----------------------------------------------*- Python -*-===##
##
# The LLVM Compiler Infrastructure
##
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
##
##===----------------------------------------------------------------------===##


import curses

import lldb
import lldbutil

from optparse import OptionParser
import os
import signal
import sys

import 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()
