import os, sys, psutil

panelPath = os.getenv('BT_PANEL')
os.chdir(panelPath)
sys.path.insert(0, panelPath + "/class/")

import public, re, json, win32api, datetime, time
from panelAuth import Plugin


class main:
    def get_cpu_list(self, get):
        """
        获取占用CPU前五的进程
        """
        plugin_obj = Plugin(False)
        Plugin_list = plugin_obj.get_plugin_list()
        ped = int(Plugin_list['ltd']) > time.time()
        if not ped: return public.returnMsg(False, "该功能为企业版专享！")
        
        slist = []
        num = psutil.cpu_count()
        
        for proc in psutil.process_iter(
            ['pid', 'name', 'username', 'cpu_percent', 'exe', 'create_time', 'cwd', 'cmdline']):
            try:
                if proc.info['name'] in ['System Idle Process', 'System', 'smss.exe', 'csrss.exe']:
                    continue
                data = {}
                data['pid'] = proc.info['pid']
                data['name'] = proc.info['name']
                data['username'] = proc.info['username']
                data['cpu_percent'] = str(round(proc.info['cpu_percent'] / num, 2)) + '%'
                if 'exe' in proc.info and proc.info['exe']:
                    data['exe'] = proc.info['exe']
                    data['f_info'] = self.__get_file_info(data['exe'])
                else:
                    data['exe'] = ''
                    data['f_info'] = ''
                create_time = datetime.datetime.fromtimestamp(proc.info['create_time'])
                run_time_seconds = (datetime.datetime.now() - create_time).total_seconds()
                run_time_days, remainder = divmod(run_time_seconds, 86400)
                run_time_hours, remainder = divmod(remainder, 3600)
                run_time_minutes, remainder = divmod(remainder, 60)
                # run_time = datetime.datetime.now() - create_time
                # data['run_time'] = str(run_time).split('.')[0]
                data['run_time'] = '{:.0f}天{:.0f}小时{:.0f}分钟'.format(run_time_days, run_time_hours,
                                                                         run_time_minutes)
                try:
                    data['cwd'] = proc.info['cwd']
                except:
                    data['cwd'] = ''
                    data['cmdline'] = proc.info['cmdline']
                slist.append(data)
            except:
                pass
        cpu = sorted(slist, key=lambda x: x['cpu_percent'], reverse=True)[:5]
        return cpu

    
    def get_mem_list(self, get):
        """
        获取占用内存前五的进程
        """
        plugin_obj = Plugin(False)
        Plugin_list = plugin_obj.get_plugin_list()
        ped = int(Plugin_list['ltd']) > time.time()
        if not ped: return public.returnMsg(False, "该功能为企业版专享！")
        process_list = []
        for process in psutil.process_iter(
            ['pid', 'name', 'username', 'memory_percent', 'memory_info', 'exe', 'create_time']):
            try:
                if process.info['name'] in ['', 'System Idle Process'] or process.info['memory_percent'] < 0.1:
                    continue
                memory_info = process.info['memory_info']
                if memory_info.rss > 0:
                    process_list.append(process.info)
            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                pass
        sorted_process_list = sorted(process_list, key=lambda x: x['memory_info'].rss, reverse=True)
        top_five_process_list = sorted_process_list[:5]
        result = []
        for proc in top_five_process_list:
            data = {}
            data['pid'] = proc['pid']
            data['name'] = proc['name']
            data['username'] = proc['username']
            data['mem'] = public.to_size(proc['memory_info'].rss)
            data['f_info'] = ''
            if 'exe' in proc and proc['exe']:
                data['exe'] = proc['exe']
                data['f_info'] = self.__get_file_info(data['exe'])
            else:
                data['exe'] = ''
                data['f_info'] = ''
            create_time = datetime.datetime.fromtimestamp(proc['create_time'])
            run_time_seconds = (datetime.datetime.now() - create_time).total_seconds()
            run_time_days, remainder = divmod(run_time_seconds, 86400)
            run_time_hours, remainder = divmod(remainder, 3600)
            run_time_minutes, remainder = divmod(remainder, 60)
            data['run_time'] = '{:.0f}天{:.0f}小时{:.0f}分钟'.format(run_time_days, run_time_hours, run_time_minutes)
            result.append(data)
        return result
    
    
    def __get_file_info(self, file_path):
        """
        获取文件描述
        """
        propNames = ['Comments', 'InternalName', 'ProductName', 'CompanyName', 'LegalCopyright', 'ProductVersion',
                     'FileDescription', 'LegalTrademarks', 'PrivateBuild', 'FileVersion', 'OriginalFilename',
                     'SpecialBuild']
        props = {'FixedFileInfo': '', 'StringFileInfo': '', 'FileVersion': ''}
        try:
            fixedInfo = win32api.GetFileVersionInfo(file_path, '\\')
            props['FixedFileInfo'] = fixedInfo
            props['FileVersion'] = "%d.%d.%d.%d" % (
                fixedInfo['FileVersionMS'] / 65536, fixedInfo['FileVersionMS'] % 65536,
                fixedInfo['FileVersionLS'] / 65536,
                fixedInfo['FileVersionLS'] % 65536)
            
            lang, codepage = win32api.GetFileVersionInfo(file_path, '\\VarFileInfo\\Translation')[0]
            
            strInfo = {}
            for propName in propNames:
                strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
                strInfo[propName] = win32api.GetFileVersionInfo(file_path, strInfoPath)
                if not strInfo[propName]: strInfo[propName] = ''
            
            return strInfo
        except:
            pass
        return None
    
    
    def kill_processes(self, get):
        if not hasattr(get, 'pid'): return False
        pid = int(get.pid)
        try:
            p = psutil.Process(pid)
            if 'python' in p.name().lower():
                return public.returnMsg(False, "禁止结束Python程序！")
            p.terminate()
            return public.returnMsg(True, "当前进程已结束")
        except psutil.NoSuchProcess:
            return public.returnMsg(False, "当前进程不存在")
