#!/usr/bin/python
#======================================================================
#
# Project	 : hpp_IOStressTest
# File 		 : Libs/IOST_Terminal/IOST_Terminal.py
# Date		 : Sep 21, 2016
# Author	 : HuuHoang Nguyen
# Contact	 : hhnguyen@apm.com
#            : hoangnh.hpp@gmail.com
# License    : MIT License
# Copyright  : 2016
# Description: The hpp_IOStressTest is under the MIT License, a copy of license which may be found in LICENSE
#
#======================================================================

import io
import os
import sys
import time
import base64 

from IOST_Host  import *

from Libs       import IOST_Basic
from Libs       import IOST_Define
from Libs       import IOST_Config

import vte
import ConfigParser
import pango

#======================================================================
_COPY =      ["copy"]
_PASTE =     ["paste"]
_COPY_ALL =  ["copy_all"]
_SAVE =      ["save"]
_FIND =      ["find"]
_CLEAR =     ["clear"]
_RESET =     ["reset"]

_FIND_NEXT = ["find_next"]
_FIND_BACK = ["find_back"]
_CONSOLE_PREV = ["console_previous"]
_CONSOLE_NEXT = ["console_next"]
_CONSOLE_1 = ["console_1"]
_CONSOLE_2 = ["console_2"]
_CONSOLE_3 = ["console_3"]
_CONSOLE_4 = ["console_4"]
_CONSOLE_5 = ["console_5"]
_CONSOLE_6 = ["console_6"]
_CONSOLE_7 = ["console_7"]
_CONSOLE_8 = ["console_8"]
_CONSOLE_9 = ["console_9"]
_CONSOLE_CLOSE = ["console_close"]
_CONSOLE_RECONNECT = ["console_reconnect"]
_CONNECT = ["connect"]

shortcuts={
    'CTRL+SHIFT+C' : _COPY ,
    'CTRL+SHIFT+V' : _PASTE,
    'CTRL+SHIFT+A' : _COPY_ALL,
    'CTRL+S'       : _SAVE,
    'CTRL+K'       : _CLEAR,
    'CTRL+R'       : _RESET
}

#======================================================================
class IOST_Terminal(IOST_Basic, IOST_Define, IOST_Host):
    """
    This is a class to register and control a terminal in python use vte module
    """
    #----------------------------------------------------------------------
    def __init__(self, notebook, host_name):
        """
        Initialization to register a vte terminal
        """
        try:
            #------------------------------------            
            self.IOST_vte = vte.Terminal()
            self.IOST_vte.set_word_chars(IOST_Define.WORD_SEPARATORS)
            self.IOST_vte.set_scrollback_lines(IOST_Define.BUFFER_LINES)
            if self.IOST_vte.get_emulation() != os.getenv("TERM"):
                os.environ['TERM'] = self.IOST_vte.get_emulation()
            #------------------------------------
            if isinstance(host_name, basestring):                
                iost_host = IOST_Host('', host_name)
                # iost_host.__print_arg__()
                
            fcolor = iost_host.font_color
            bcolor = iost_host.back_color

            #------------------------------------
            if fcolor == '' or fcolor ==None or bcolor == '' or bcolor ==None:
                    fcolor = IOST_Define.FONT_COLOR
                    bcolor = IOST_Define.BACKGROUND_COLOR
            
            #------------------------------------
            if len(fcolor) > 0 and len(bcolor) > 0:
                self.IOST_vte.set_colors(gtk.gdk.Color(fcolor), gtk.gdk.Color(bcolor), [])
                              
            #------------------------------------
            if len(IOST_Define.FONT) == 0:
                IOST_Define.FONT = 'monospace'
            else:
                self.IOST_vte.set_font(pango.FontDescription(IOST_Define.FONT))
            
            #------------------------------------
            # scrollPane = gtk.ScrolledWindow()
            # scrollPane.connect('button_press_event', lambda *args: True)

            #------------------------------------
            self.IOST_vte.connect("child-exited", lambda object: on_Terminal_Done(self, done=None))
            self.IOST_vte.connect("focus", self.on_Terminal_Tab_focus )
            self.IOST_vte.connect("button_press_event", self.on_Terminal_click )
            self.IOST_vte.connect("key_press_event", self.on_Terminal_keypress )
            self.IOST_vte.connect("selection-changed", self.on_Terminal_selection )
            
            #------------------------------------
            self.real_transparency = False
            if IOST_Define.TRANSPARENCY > 0:
                self.real_transparency = self.get_real_transparency()

                if not self.self.real_transparency:
                    self.IOST_vte.set_background_transparent(True)
                    self.IOST_vte.set_background_saturation(IOST_Define.TRANSPARENCY / 100.0)
                    if len(bcolor) > 0:
                        self.IOST_vte.set_background_tint_color(gtk.gdk.Color(bcolor))
                else:
                    self.IOST_vte.set_opacity(int( (100 - conf.TRANSPARENCY) / 100.0 * 65535) )
            
            self.IOST_vte.set_backspace_binding(iost_host.backspace_key)            
            self.IOST_vte.set_delete_binding(iost_host.delete_key)   

            while gtk.events_pending():
                gtk.main_iteration(False)
                        
        except:          
            iost_basic = IOST_Basic()
            iost_basic.MsgBox("%s: %s" %(("Error to create a Terminal"), sys.exc_info()[1]))
        
       
    
    #----------------------------------------------------------------------
    def on_Terminal_Tab_focus(self, object, *args):
        if isinstance(object, vte.Terminal):
            self.current = object

    #----------------------------------------------------------------------
    def on_Terminal_click(self, object, event, *args):
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
            if IOST_Define.PASTE_ON_RIGHT_CLICK:
                object.paste_clipboard()
            else:
                pass
                #Need add code more here
            
            return True
    
    #----------------------------------------------------------------------
    def on_Terminal_keypress(self, object, event, *args):
        IOST_Basic.__init__(self)
        if shortcuts.has_key(self.GetKeyName(event)):
                        
            cmd = shortcuts[self.GetKeyName(event)]
            if type(cmd) == list:                
                if cmd == _COPY:
                    self.Terminal_Copy(object)
                elif cmd == _PASTE:
                    self.Terminal_Paste(object)
                elif cmd == _COPY_ALL:
                    self.Terminal_CopyAll(object)
                elif cmd == _SAVE:
                    self.Terminal_ShowSaveBuffer(object)
                elif cmd == _FIND:
                    pass
                elif cmd == _FIND_NEXT:
                    if hasattr(self, 'search'):
                        self.Terminal_FindWord()
                elif cmd == _CLEAR:
                    object.reset(True, True)                    
                elif cmd == _RESET:
                    object.reset(True, False)
                elif cmd == _FIND_BACK:
                    if hasattr(self, 'seatch'):
                        self.Terminal_FindWord(backwards=True)
                elif cmd == _CONSOLE_PREV:
                    object.get_parent().get_parent().prev_page()
                elif cmd == _CONSOLE_NEXT:
                    object.get_parent().get_parent().next_page()
                elif cmd == _CONSOLE_CLOSE:
                    obj_id = object.get_parent()
                    page   = object.get_parent().get_parent().page_num(obj_id)
                    if page != -1:
                         object.get_parent().get_parent().remove_page(page)
                         obj_id.destroy()
                elif cmd == _CONSOLE_RECONNECT:
                    if not hasattr(object, "command"):
                        object.fork_command(SHELL)
                    else:
                        object.fork_command(object.command[0], object.command[1])
                        while gtk.events_pending():
                            gtk.main_iteration(False)

                        if object.command[2] != None and object.command[2]!='':
                            gobject.timeout_add(2000, self.Terminal_SendData, object, object.command[2])
                    
                    object.get_parent().get_parent().get_tab_label(object.get_parent()).Terminal_MarkTabActive()
                
                elif cmd == _CONNECT:
                    pass
                elif cmd[0][0:8] == "console_":
                    page = int(cmd[0][8:]) - 1
                    object.get_parent().get_parent().set_current_page(page)
            else:
                object.feed_child(cmd)

            return True

        return False                
    
    #----------------------------------------------------------------------
    def on_Terminal_selection(self, object, *args):
        if IOST_Define.AUTO_COPY_SELECTION:
            self.Terminal_Copy(object)
        return True
    
    #----------------------------------------------------------------------
    def Terminal_Copy(self, terminal):
        ""
        terminal.copy_clipboard()
        
    #----------------------------------------------------------------------
    def Terminal_Paste(self, terminal):
        ""
        terminal.paste_clipboard()
    
    #----------------------------------------------------------------------
    def Terminal_CopyAndPaste(self, terminal):
        ""
        terminal.copy_clipboard()
        terminal.paste_clipboard()

    #----------------------------------------------------------------------
    def Terminal_SelectAll(self, terminal):
        ""
        terminal.select_all()

    #----------------------------------------------------------------------
    def Terminal_CopyAll(self, terminal):
        ""
        terminal.select_all()
        terminal.copy_clipboard()
        terminal.select_none()

    #----------------------------------------------------------------------
    def Terminal_ShowSaveBuffer(self, terminal):
        dlg = gtk.FileChooserDialog(title="Save file log",  action=gtk.FILE_CHOOSER_ACTION_SAVE)
        dlg.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        dlg.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_OK)
        dlg.set_do_overwrite_confirmation(True)
        dlg.set_current_name( os.path.basename("IOST_Log-%s.txt" % (time.strftime("%Y%m%d%H%M%S")) ))
        if not hasattr(self,'lastPath'):
            self.lastPath = os.path.expanduser("~")
        dlg.set_current_folder( self.lastPath )

        if dlg.run() == gtk.RESPONSE_OK:
            filename = dlg.get_filename()
            self.lastPath = os.path.dirname(filename)

            try:
                buff = terminal.get_text_range(0, 0, terminal.get_property('scrollback-lines')-1, terminal.get_column_count()-1, lambda *args: True, None, None ).strip()
                f = open(filename, "w")
                f.write(buff)
                f.close()
            except:
                dlg.destroy()
                msgbox("%s: %s" % (_("Can't open file for writting"), filename) )
                return

        dlg.destroy()

    #----------------------------------------------------------------------
    def Terminal_FindWord(self, backwards=False):
        ""
        pass
    #----------------------------------------------------------------------
    def Terminal_SendData(self, terminal, data):
        terminal.feed_child('%s\r' %(data))
        return False
    
    def Terminal_SendCMD(self, terminal, cmd):
        pid = terminal.fork_command(cmd[0],cmd)
        print 'cmd : ', cmd
        print 'pid', pid
        return False
    
    def Terminal_CheckDone(self, pid):
        while pid_running(pid):
            time.sleep(.25)
            os.system("ps -e | grep %s" %pid)
        return False

    #     def is_running(pid):        
    # try:
    #     os.kill(pid, 0)
    # except OSError:
    #     return False

    # return True

    #----------------------------------------------------------------------
    def Terminal_MarkTabActive(self):
        # self.label.set_markup("%s" % (self.label.get_text()))
        # self.is_active = True
        pass
        
    #----------------------------------------------------------------------
    def Terminal_GetRealTransparency(self):
        # add code more here 
        return self.real_transparency
    
    def on_Terminal_Done(self, done=None):
        print "Finished"

    #----------------------------------------------------------------------
def pid_running(pid):        
    try:
        res = os.kill(pid, 0)
        print "res = ", res
        if res=='None':
            return True
    except OSError:
        return False

    return True


    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
    #----------------------------------------------------------------------
