#-*- coding: utf-8 -*-

# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

# from __future__ import absolute_import
from calculate.consolegui import qt

from .pid_information import client_list_pid, client_pid_info
from .more import LabelWordWrap, show_msg, get_sid, ClientServiceThread
class ViewProc(qt.QWidget):
    def __init__(self, parent, ClientObj):
        super().__init__(parent)
        self.ClientObj = ClientObj
        self.client = ClientObj.client
        self.pid = 0
        client_pid_info(ClientObj, ClientObj.client, 0)
        list_pid = client_list_pid(self.ClientObj.client)
        ClientObj._parent.setWindowTitle (
                            _('View information about the running processes')\
                            + ' - ' + self.ClientObj.Name)
        
        self.label_list = []
        self.button_list = []
        self.status_list = []
        self.grid_layout = qt.QGridLayout()
        self.helpLabel = LabelWordWrap \
                     (_('View information about the running processes'), self)
        self.grid_layout.addWidget(self.helpLabel, 0, 0, 1, 0)
        
        if not list_pid:
            list_pid = []
            
        for num in range (0, len(list_pid)):
            #if list_pid[num] == ClientObj._parent.sys_update_pid:
            #    continue
            # add method name
            if 'method_name' in self.ClientObj.process_dict[str(list_pid[num])]:
                method_name = self.ClientObj.process_dict[str(list_pid[num])] \
                                                              ['method_name']
            else:
                method_name = self.ClientObj.process_dict[str(list_pid[num])] \
                                                                     ['name']
            method_name = str(method_name)
            if method_name in self.ClientObj.method_names:
                view_method_name = str(self.ClientObj.method_names[method_name])
            
#            try:
#                view_method_name = self.ClientObj.param_objects \
#                                            [method_name]['view_method_name']
#            except:
            else:
                view_method_name = method_name
            
            # try:
            #     view_method_name = view_method_name.encode('utf-8')
            # except (UnicodeEncodeError, UnicodeDecodeError):
            #     pass

            self.label_list.append(LabelWordWrap(str(view_method_name), self))
            self.grid_layout.addWidget(self.label_list[num], num+2,0)
            
            # add start time process
            # del mircosec
            time_text = ClientObj.process_dict[str(list_pid[num])]['time'].\
                                                            rsplit('.', 1)[0]
            self.grid_layout.addWidget(LabelWordWrap(time_text, self), num+2,1)

            # add status button
            if self.ClientObj.process_dict[str(list_pid[num])]['status'] == '1':
                kill_but_text = _('Kill the process? (It\'s active)')
                kill_button = qt.QPushButton(kill_but_text, self)
                kill_button.clicked.connect(self.kill_process \
                            (int(list_pid[num]), num+2, 2))
                self.status_list.append(kill_button)
                
            if self.ClientObj.process_dict[str(list_pid[num])]['status'] =='0':
                self.status_list.append(LabelWordWrap \
                                      (_('Process successful completed'), self))
            if self.ClientObj.process_dict[str(list_pid[num])]['status'] =='2':
                self.status_list.append(LabelWordWrap \
                                                  (_('Process failed'), self))
                
            self.grid_layout.addWidget(self.status_list[num], num+2, 2)
                
            # add 'View result' button
            button_text = _('View the result, PID %s') %str(list_pid[num])

            Button = qt.QPushButton(button_text, self)
            
            Button.clicked.connect(self.onActivated(str(list_pid[num]), \
                                                    str(view_method_name)))
            
            self.button_list.append(Button)
            self.grid_layout.addWidget(self.button_list[num], num+2, 3)
        
        if not len(list_pid):
            self.grid_layout.addWidget(LabelWordWrap(_('No running processes'
                                            ' in the current session'), self))

        else:
            self.grid_layout.addWidget(LabelWordWrap(_('Task name'), self),1,0)
            self.grid_layout.addWidget(LabelWordWrap(_('Start time'),self),1,1)
            self.grid_layout.addWidget(LabelWordWrap(_('Status'), self), 1,2)
            lbl = LabelWordWrap(_('Result'), self)
            lbl.setMinimumHeight(lbl.sizeHint().height()*3)
            self.grid_layout.addWidget(lbl, 1,3)

        # for clear memory after closed this window
        self.setAttribute(qt.Qt.WA_DeleteOnClose)

        self.grid_layout.setAlignment(qt.Qt.AlignTop)

        self.setLayout(self.grid_layout)
        self.show()

    def onActivated(self, pid, method_name):
        def wrapper():
#            pid = self.sender().text()
            for i in self.ClientObj.process_dict:
                if i == pid:
                    # set new window title
                    name = method_name
                    # n = method_name
                    # try:
                    #     # name = n.decode('utf-8')
                    #     name = n
                    # except (UnicodeEncodeError, UnicodeDecodeError):
                    #     pass
                    self.ClientObj._parent.setWindowTitle \
                                    (self.ClientObj._parent.windowTitle() +
                                    ' - ' + name)
    #                try:
    #                    self.ClientObj.process_dict[i]['result']
    #                except:
    #                    self.ClientObj.process_dict[i]['result'] = {}
                    self.ClientObj.MainWidget.main_view_process \
                            (self.ClientObj.process_dict[i]['method_name'], \
                            self.ClientObj.process_dict[i]['result'], str(i))
                    self.ClientObj.app.processEvents()
                    self.ClientObj.MainWidget.main_frame.verticalScrollBar() \
                                     .setValue(self.ClientObj.MainWidget. \
                                     main_frame.verticalScrollBar().maximum())
                    break
        return wrapper

    def kill_process(self, pid, x, y):
        def wrapper():
            sid = get_sid(self.client)

            # Call server method
            if hasattr (self, 'kill_process_thread'):
                if self.kill_process_thread.isRunning():
                    return 1
            self.kill_process_thread = ClientServiceThread(self.ClientObj,\
                                    'pid_kill', pid, sid)
            self.kill_process_thread.signal.connect(self.kill_process_after)
            self.kill_process_thread.start()
        return wrapper

    def kill_process_after(self, result):
        if result == 0:
            msg = _("Well killed!")
        elif result == 2:
            msg = _("Process completed")
        elif result == -1:
            msg = _("Certificate not found in the server!")
        elif result == -2:
            msg = _("Session not matching your certificate!")
        elif result == 1:
            msg = _("Failed to kill the process!")
        else:
            msg = 'error'
        
        show_msg(msg)
        self.ClientObj.MainWidget.view_processes()        
        
    def closeEvent(self, event):
        if hasattr (self, 'kill_process_thread'):
            if self.kill_process_thread.isRunning():
                self.kill_process_thread.close()
                self.kill_process_thread.wait()
        event.accept()
