#
# BitBake Curses UI Implementation
#
# Implements an ncurses frontend for the BitBake utility.
#
# Copyright (C) 2006 Michael 'Mickey' Lauer
# Copyright (C) 2006-2007 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""
    We have the following windows:

        1.) Main Window: Shows what we are ultimately building and how far we are. Includes status bar
        2.) Thread Activity Window: Shows one status line for every concurrent bitbake thread.
        3.) Command Line Window: Contains an interactive command line where you can interact w/ Bitbake.

    Basic window layout is like that:

        |---------------------------------------------------------|
        | <Main Window>               | <Thread Activity Window>  |
        |                             | 0: foo do_compile complete|
        | Building Gtk+-2.6.10        | 1: bar do_patch complete  |
        | Status: 60%                 | ...                       |
        |                             | ...                       |
        |                             | ...                       |
        |---------------------------------------------------------|
        |<Command Line Window>                                    |
        |>>> which virtual/kernel                                 |
        |openzaurus-kernel                                        |
        |>>> _                                                    |
        |---------------------------------------------------------|

"""


from __future__ import division
import logging
import os, sys, itertools, time, subprocess

try:
    import curses
except ImportError:
    sys.exit("FATAL: The ncurses ui could not load the required curses python module.")

import bb
import xmlrpclib
from bb import ui
from bb.ui import uihelper

parsespin = itertools.cycle( r'|/-\\' )

X = 0
Y = 1
WIDTH = 2
HEIGHT = 3

MAXSTATUSLENGTH = 32

class NCursesUI:
    """
    NCurses UI Class
    """
    class Window:
        """Base Window Class"""
        def __init__( self, x, y, width, height, fg=curses.COLOR_BLACK, bg=curses.COLOR_WHITE ):
            self.win = curses.newwin( height, width, y, x )
            self.dimensions = ( x, y, width, height )
            """
            if curses.has_colors():
                color = 1
                curses.init_pair( color, fg, bg )
                self.win.bkgdset( ord(' '), curses.color_pair(color) )
            else:
                self.win.bkgdset( ord(' '), curses.A_BOLD )
            """
            self.erase()
            self.setScrolling()
            self.win.noutrefresh()

        def erase( self ):
            self.win.erase()

        def setScrolling( self, b = True ):
            self.win.scrollok( b )
            self.win.idlok( b )

        def setBoxed( self ):
            self.boxed = True
            self.win.box()
            self.win.noutrefresh()

        def setText( self, x, y, text, *args ):
            self.win.addstr( y, x, text, *args )
            self.win.noutrefresh()

        def appendText( self, text, *args ):
            self.win.addstr( text, *args )
            self.win.noutrefresh()

        def drawHline( self, y ):
            self.win.hline( y, 0, curses.ACS_HLINE, self.dimensions[WIDTH] )
            self.win.noutrefresh()

    class DecoratedWindow( Window ):
        """Base class for windows with a box and a title bar"""
        def __init__( self, title, x, y, width, height, fg=curses.COLOR_BLACK, bg=curses.COLOR_WHITE ):
            NCursesUI.Window.__init__( self, x+1, y+3, width-2, height-4, fg, bg )
            self.decoration = NCursesUI.Window( x, y, width, height, fg, bg )
            self.decoration.setBoxed()
            self.decoration.win.hline( 2, 1, curses.ACS_HLINE, width-2 )
            self.setTitle( title )

        def setTitle( self, title ):
            self.decoration.setText( 1, 1, title.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD )

    #-------------------------------------------------------------------------#
#    class TitleWindow( Window ):
    #-------------------------------------------------------------------------#
#        """Title Window"""
#        def __init__( self, x, y, width, height ):
#            NCursesUI.Window.__init__( self, x, y, width, height )
#            version = bb.__version__
#            title = "BitBake %s" % version
#            credit = "(C) 2003-2007 Team BitBake"
#            #self.win.hline( 2, 1, curses.ACS_HLINE, width-2 )
#            self.win.border()
#            self.setText( 1, 1, title.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD )
#            self.setText( 1, 2, credit.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD )

    #-------------------------------------------------------------------------#
    class ThreadActivityWindow( DecoratedWindow ):
    #-------------------------------------------------------------------------#
        """Thread Activity Window"""
        def __init__( self, x, y, width, height ):
            NCursesUI.DecoratedWindow.__init__( self, "Thread Activity", x, y, width, height )

        def setStatus( self, thread, text ):
            line = "%02d: %s" % ( thread, text )
            width = self.dimensions[WIDTH]
            if ( len(line) > width ):
                line = line[:width-3] + "..."
            else:
                line = line.ljust( width )
            self.setText( 0, thread, line )

    #-------------------------------------------------------------------------#
    class MainWindow( DecoratedWindow ):
    #-------------------------------------------------------------------------#
        """Main Window"""
        def __init__( self, x, y, width, height ):
            self.StatusPosition = width - MAXSTATUSLENGTH
            NCursesUI.DecoratedWindow.__init__( self, None, x, y, width, height )
            curses.nl()

        def setTitle( self, title ):
            title = "BitBake %s" % bb.__version__
            self.decoration.setText( 2, 1, title, curses.A_BOLD )
            self.decoration.setText( self.StatusPosition - 8, 1, "Status:", curses.A_BOLD )

        def setStatus(self, status):
            while len(status) < MAXSTATUSLENGTH:
                status = status + " "
            self.decoration.setText( self.StatusPosition, 1, status, curses.A_BOLD )


    #-------------------------------------------------------------------------#
    class ShellOutputWindow( DecoratedWindow ):
    #-------------------------------------------------------------------------#
        """Interactive Command Line Output"""
        def __init__( self, x, y, width, height ):
            NCursesUI.DecoratedWindow.__init__( self, "Command Line Window", x, y, width, height )

    #-------------------------------------------------------------------------#
    class ShellInputWindow( Window ):
    #-------------------------------------------------------------------------#
        """Interactive Command Line Input"""
        def __init__( self, x, y, width, height ):
            NCursesUI.Window.__init__( self, x, y, width, height )

# put that to the top again from curses.textpad import Textbox
#            self.textbox = Textbox( self.win )
#            t = threading.Thread()
#            t.run = self.textbox.edit
#            t.start()

    #-------------------------------------------------------------------------#
    def main(self, stdscr, server, eventHandler, params):
    #-------------------------------------------------------------------------#
        height, width = stdscr.getmaxyx()

        # for now split it like that:
        # MAIN_y + THREAD_y = 2/3 screen at the top
        # MAIN_x = 2/3 left, THREAD_y = 1/3 right
        # CLI_y = 1/3 of screen at the bottom
        # CLI_x = full

        main_left = 0
        main_top = 0
        main_height = ( height // 3 * 2 )
        main_width = ( width // 3 ) * 2
        clo_left = main_left
        clo_top = main_top + main_height
        clo_height = height - main_height - main_top - 1
        clo_width = width
        cli_left = main_left
        cli_top = clo_top + clo_height
        cli_height = 1
        cli_width = width
        thread_left = main_left + main_width
        thread_top = main_top
        thread_height = main_height
        thread_width = width - main_width

        #tw = self.TitleWindow( 0, 0, width, main_top )
        mw = self.MainWindow( main_left, main_top, main_width, main_height )
        taw = self.ThreadActivityWindow( thread_left, thread_top, thread_width, thread_height )
        clo = self.ShellOutputWindow( clo_left, clo_top, clo_width, clo_height )
        cli = self.ShellInputWindow( cli_left, cli_top, cli_width, cli_height )
        cli.setText( 0, 0, "BB>" )

        mw.setStatus("Idle")

        helper = uihelper.BBUIHelper()
        shutdown = 0

        try:
            params.updateFromServer(server)
            cmdline = params.parseActions()
            if not cmdline:
                print("Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.")
                return 1
            if 'msg' in cmdline and cmdline['msg']:
                logger.error(cmdline['msg'])
                return 1
            cmdline = cmdline['action']
            ret, error = server.runCommand(cmdline)
            if error:
                print("Error running command '%s': %s" % (cmdline, error))
                return
            elif ret != True:
                print("Couldn't get default commandlind! %s" % ret)
                return
        except xmlrpclib.Fault as x:
            print("XMLRPC Fault getting commandline:\n %s" % x)
            return

        exitflag = False
        while not exitflag:
            try:
                event = eventHandler.waitEvent(0.25)
                if not event:
                    continue

                helper.eventHandler(event)
                if isinstance(event, bb.build.TaskBase):
                    mw.appendText("NOTE: %s\n" % event._message)
                if isinstance(event, logging.LogRecord):
                    mw.appendText(logging.getLevelName(event.levelno) + ': ' + event.getMessage() + '\n')

                if isinstance(event, bb.event.CacheLoadStarted):
                    self.parse_total = event.total
                if isinstance(event, bb.event.CacheLoadProgress):
                    x = event.current
                    y = self.parse_total
                    mw.setStatus("Loading Cache:   %s [%2d %%]" % ( next(parsespin), x*100/y ) )
                if isinstance(event, bb.event.CacheLoadCompleted):
                    mw.setStatus("Idle")
                    mw.appendText("Loaded %d entries from dependency cache.\n"
                                % ( event.num_entries))

                if isinstance(event, bb.event.ParseStarted):
                    self.parse_total = event.total
                if isinstance(event, bb.event.ParseProgress):
                    x = event.current
                    y = self.parse_total
                    mw.setStatus("Parsing Recipes: %s [%2d %%]" % ( next(parsespin), x*100/y ) )
                if isinstance(event, bb.event.ParseCompleted):
                    mw.setStatus("Idle")
                    mw.appendText("Parsing finished. %d cached, %d parsed, %d skipped, %d masked.\n"
                                % ( event.cached, event.parsed, event.skipped, event.masked ))

#                if isinstance(event, bb.build.TaskFailed):
#                    if event.logfile:
#                        if data.getVar("BBINCLUDELOGS", d):
#                            bb.error("log data follows (%s)" % logfile)
#                            number_of_lines = data.getVar("BBINCLUDELOGS_LINES", d)
#                            if number_of_lines:
#                                subprocess.call('tail -n%s %s' % (number_of_lines, logfile), shell=True)
#                            else:
#                                f = open(logfile, "r")
#                                while True:
#                                    l = f.readline()
#                                    if l == '':
#                                        break
#                                    l = l.rstrip()
#                                    print '| %s' % l
#                                f.close()
#                        else:
#                            bb.error("see log in %s" % logfile)

                if isinstance(event, bb.command.CommandCompleted):
                    # stop so the user can see the result of the build, but
                    # also allow them to now exit with a single ^C
                    shutdown = 2
                if isinstance(event, bb.command.CommandFailed):
                    mw.appendText("Command execution failed: %s" % event.error)
                    time.sleep(2)
                    exitflag = True
                if isinstance(event, bb.command.CommandExit):
                    exitflag = True
                if isinstance(event, bb.cooker.CookerExit):
                    exitflag = True

                if isinstance(event, bb.event.LogExecTTY):
                    mw.appendText('WARN: ' + event.msg + '\n')
                if helper.needUpdate:
                    activetasks, failedtasks = helper.getTasks()
                    taw.erase()
                    taw.setText(0, 0, "")
                    if activetasks:
                        taw.appendText("Active Tasks:\n")
                        for task in activetasks.itervalues():
                            taw.appendText(task["title"] + '\n')
                    if failedtasks:
                        taw.appendText("Failed Tasks:\n")
                        for task in failedtasks:
                            taw.appendText(task["title"] + '\n')

                curses.doupdate()
            except EnvironmentError as ioerror:
                # ignore interrupted io
                if ioerror.args[0] == 4:
                    pass

            except KeyboardInterrupt:
                if shutdown == 2:
                    mw.appendText("Third Keyboard Interrupt, exit.\n")
                    exitflag = True
                if shutdown == 1:
                    mw.appendText("Second Keyboard Interrupt, stopping...\n")
                    _, error = server.runCommand(["stateForceShutdown"])
                    if error:
                        print("Unable to cleanly stop: %s" % error)
                if shutdown == 0:
                    mw.appendText("Keyboard Interrupt, closing down...\n")
                    _, error = server.runCommand(["stateShutdown"])
                    if error:
                        print("Unable to cleanly shutdown: %s" % error)
                shutdown = shutdown + 1
                pass

def main(server, eventHandler, params):
    if not os.isatty(sys.stdout.fileno()):
        print("FATAL: Unable to run 'ncurses' UI without a TTY.")
        return
    ui = NCursesUI()
    try:
        curses.wrapper(ui.main, server, eventHandler, params)
    except:
        import traceback
        traceback.print_exc()
