# coding:utf-8

# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------

import os
from datetime import datetime

import core.mw as mw

__months = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
            'Jul': '07', 'Aug': '08', 'Sep': '09', 'Sept': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'}

def getAuditLogsFiles():
    log_dir = '/var/log'
    log_files = []
    for log_file in os.listdir(log_dir):
        log_suffix = log_file.split('.')[-1:]
        if log_suffix[0] in ['gz', 'xz', 'bz2', 'asl']:
            continue

        if log_file in ['.', '..']:
            continue

        filename = os.path.join(log_dir, log_file)
        if not os.path.exists(filename):
            continue

        if os.path.isfile(filename):
            file_size = os.path.getsize(filename)
            if not file_size:
                continue

            tmp = {
                'name': log_file,
                'size': file_size,
                'log_file': filename,
                'title': getLogsTitle(log_file),
                'uptime': os.path.getmtime(filename)
            }

            log_files.append(tmp)
        else:
            for next_name in os.listdir(filename):
                if next_name[-3:] in ['.gz', '.xz']:
                    continue
                next_file = os.path.join(filename, next_name)
                if not os.path.isfile(next_file):
                    continue
                file_size = os.path.getsize(next_file)
                if not file_size:
                    continue
                log_name = '{}/{}'.format(log_file, next_name)
                tmp = {
                    'name': log_name,
                    'size': file_size,
                    'log_file': next_file,
                    'title': getLogsTitle(log_name),
                    'uptime': os.path.getmtime(next_file)
                }
                log_files.append(tmp)
    log_files = sorted(log_files, key=lambda x: x['name'], reverse=True)
    return log_files

def __to_date2(date_str):
    tmp = date_str.split()
    s_date = str(tmp[-1]) + '-' + __months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
    return s_date

def __to_date3(date_str):
    tmp = date_str.split()
    s_date = str(datetime.now().year) + '-' + __months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
    return s_date

def __to_date4(date_str):
    tmp = date_str.split()
    s_date = str(datetime.now().year) + '-' + __months.get(tmp[0], tmp[0]) + '-' + tmp[1] + ' ' + tmp[2]
    return s_date

def parseAuditFile(log_name, result):
    log_list = []
    is_string = True
    for _line in result.split("\n"):
        if not _line.strip():
            continue
        if log_name.find('sa/sa') == -1:
            if _line[:3] in __months:
                _msg = _line[16:]
                _tmp = _msg.split(": ")
                _act = ''
                if len(_tmp) > 1:
                    _act = _tmp[0]
                    _msg = _tmp[1]
                else:
                    _msg = _tmp[0]
                _line = {
                    "时间": __to_date4(_line[:16].strip()),
                    "角色": _act,
                    "事件": _msg
                }
                is_string = False
            elif _line[:2] in ['19', '20', '21', '22', '23', '24']:
                _msg = _line[19:]
                _tmp = _msg.split(" ")
                _act = _tmp[1]
                _msg = ' '.join(_tmp[2:])
                _line = {
                    "时间": _line[:19].strip(),
                    "角色": _act,
                    "事件": _msg
                }
                is_string = False
            elif log_name.find('alternatives') == 0:
                _tmp = _line.split(": ")
                _last = _tmp[0].split(" ")
                _act = _last[0]
                _msg = ' '.join(_tmp[1:])
                _line = {
                    "时间": ' '.join(_last[1:]).strip(),
                    "角色": _act,
                    "事件": _msg
                }
                is_string = False
            else:
                if not is_string:
                    if type(_line) != dict:
                        continue

        log_list.append(_line)
    return log_list

def getAuditLast(log_name):
    # 获取日志
    cmd = '''LANG=en_US.UTF-8 last -n 200 -x -f {} |grep -v 127.0.0.1|grep -v " begins"'''.format(
        '/var/log/' + log_name)
    result = mw.execShell(cmd)
    lastlog_list = []
    for _line in result[0].split("\n"):
        if not _line:
            continue
        tmp = {}
        sp_arr = _line.split()
        tmp['用户'] = sp_arr[0]
        if sp_arr[0] == 'runlevel':
            tmp['来源'] = sp_arr[4]
            tmp['端口'] = ' '.join(sp_arr[1:4])
            tmp['时间'] = __to_date3(' '.join(sp_arr[5:])) + ' ' + ' '.join(sp_arr[-2:])
        elif sp_arr[0] in ['reboot', 'shutdown']:
            tmp['来源'] = sp_arr[3]
            tmp['端口'] = ' '.join(sp_arr[1:3])
            if sp_arr[-3] == '-':
                tmp['时间'] = __to_date3(
                    ' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-3:])
            else:
                tmp['时间'] = __to_date3(
                    ' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-2:])
        elif sp_arr[1] in ['tty1', 'tty', 'tty2', 'tty3', 'hvc0', 'hvc1', 'hvc2'] or len(sp_arr) == 9:
            tmp['来源'] = ''
            tmp['端口'] = sp_arr[1]
            tmp['时间'] = __to_date3(' '.join(sp_arr[2:])) + ' ' + ' '.join(sp_arr[-3:])
        else:
            tmp['来源'] = sp_arr[2]
            tmp['端口'] = sp_arr[1]
            tmp['时间'] = __to_date3(' '.join(sp_arr[3:])) + ' ' + ' '.join(sp_arr[-3:])

        # tmp['_line'] = _line
        lastlog_list.append(tmp)
    # lastlog_list = sorted(lastlog_list,key=lambda x:x['时间'],reverse=True)
    return mw.returnData(True, 'ok!', lastlog_list)

def getAuditLastLog():
    cmd = '''LANG=en_US.UTF-8 lastlog|grep -v Username'''
    result = mw.execShell(cmd)
    lastlog_list = []
    for _line in result[0].split("\n"):
        if not _line:
            continue
        tmp = {}
        sp_arr = _line.split()
        tmp['用户'] = sp_arr[0]
        # tmp['_line'] = _line
        if _line.find('Never logged in') != -1:
            tmp['最后登录时间'] = '0'
            tmp['最后登录来源'] = '-'
            tmp['最后登录端口'] = '-'
            lastlog_list.append(tmp)
            continue
        tmp['最后登录来源'] = sp_arr[2]
        tmp['最后登录端口'] = sp_arr[1]
        tmp['最后登录时间'] = __to_date2(' '.join(sp_arr[3:]))

        lastlog_list.append(tmp)
    lastlog_list = sorted(lastlog_list, key=lambda x: x['最后登录时间'], reverse=True)
    for i in range(len(lastlog_list)):
        if lastlog_list[i]['最后登录时间'] == '0':
            lastlog_list[i]['最后登录时间'] = '从未登录过'
    return mw.returnData(True, 'ok!', lastlog_list)

def parseAuditFileLine(log_name, _line):
    is_string = True
    if log_name.find('sa/sa') == -1:
        if _line[:3] in __months:
            _msg = _line[16:]
            _tmp = _msg.split(": ")
            # print('tmp: ',_tmp)
            _act = ''
            if len(_tmp) > 1:
                _act = _tmp[0]
                _msg = _tmp[1]
            else:
                _msg = _tmp[0]
            _line = {
                "时间": __to_date4(_line[:16].strip()),
                "角色": _act,
                "事件": _msg
            }
            is_string = False
        elif _line[:2] in ['19', '20', '21', '22', '23', '24']:
            # print(_line)
            _msg = _line[19:]
            _tmp = _msg.split(" ")
            _act = _tmp[1]
            _msg = ' '.join(_tmp[2:])
            _line = {
                "时间": _line[:19].strip(),
                "角色": _act,
                "事件": _msg
            }
            is_string = False
        elif log_name.find('alternatives') == 0:
            _tmp = _line.split(": ")
            _last = _tmp[0].split(" ")
            _act = _last[0]
            _msg = ' '.join(_tmp[1:])
            _line = {
                "时间": ' '.join(_last[1:]).strip(),
                "角色": _act,
                "事件": _msg
            }
            is_string = False
        else:
            if not is_string:
                if type(_line) != dict:
                    return _line
    return _line

def parseAuditFile(log_name, result):
    log_list = []
    for _line in result.split("\n"):
        if not _line.strip():
            continue
        try:
            _line = parseAuditFileLine(log_name, _line)
        except Exception as e:
            print(str(e))
        
        log_list.append(_line)
    return log_list

def getAuditLogsName(log_name):
    if log_name in ['wtmp', 'btmp', 'utmp'] or log_name.find('wtmp') == 0 or log_name.find('btmp') == 0 or log_name.find('utmp') == 0:
        return getAuditLast(log_name)

    if log_name.find('lastlog') == 0:
        return getAuditLastLog()

    if log_name.find('sa/sa') == 0:
        if log_name.find('sa/sar') == -1:
            return mw.execShell("sar -f /var/log/{}".format(log_name))[0]
    log_dir = '/var/log'
    log_file = log_dir + '/' + log_name
    if not os.path.exists(log_file):
        return mw.returnData(False, '日志文件不存在!')
    result = mw.getLastLine(log_file, 100)
    try:
        log_list = parseAuditFile(log_name, result)
        _string = []
        _dict = []
        _list = []
        for _line in log_list:
            if isinstance(_line, str):
                _string.append(_line.strip())
            elif isinstance(_line, dict):
                _dict.append(_line)
            elif isinstance(_line, list):
                _list.append(_line)
            else:
                continue
        _str_len = len(_string)
        _dict_len = len(_dict)
        _list_len = len(_list)
        if _str_len > _dict_len + _list_len:
            return "\n".join(_string)
        elif _dict_len > _str_len + _list_len:
            return mw.returnData(True, 'ok!', _dict)
        else:
            return mw.returnData(True, 'ok!', _list)

    except Exception as e:
        # print(mw.getTracebackInfo())
        return mw.returnData(True, 'ok!', result)

def getLogsTitle(log_name):
    log_name = log_name.replace('.1', '')
    if log_name in ['mw-update.log']:
        return '面板更新日志'
    if log_name in ['mw-install.log']:
        return '面板安装日志'
    if log_name in ['auth.log', 'secure'] or log_name.find('auth.') == 0:
        return '授权日志'
    if log_name in ['dmesg'] or log_name.find('dmesg') == 0:
        return '内核缓冲区日志'
    if log_name in ['syslog'] or log_name.find('syslog') == 0:
        return '系统日志'
    if log_name in ['rsyncd.log']:
        return '远程同步日志'
    if log_name in ['btmp']:
        return '失败的登录记录'
    if log_name in ['utmp', 'wtmp']:
        return '登录和重启记录'
    if log_name in ['lastlog']:
        return '用户最后登录'
    if log_name in ['yum.log']:
        return 'yum包管理器日志'
    if log_name in ['anaconda.log']:
        return 'Anaconda日志'
    if log_name in ['dpkg.log']:
        return 'dpkg日志'
    if log_name in ['daemon.log']:
        return '系统后台守护进程日志'
    if log_name in ['boot.log']:
        return '启动日志'
    if log_name in ['kern.log']:
        return '内核日志'
    if log_name in ['maillog', 'mail.log']:
        return '邮件日志'
    if log_name.find('Xorg') == 0:
        return 'Xorg日志'
    if log_name in ['cron.log']:
        return '定时任务日志'
    if log_name in ['alternatives.log']:
        return '更新替代信息'
    if log_name in ['debug']:
        return '调试信息'
    if log_name.find('apt') == 0:
        return 'apt-get相关日志'
    if log_name.find('installer') == 0:
        return '系统安装相关日志'
    if log_name in ['messages']:
        return '综合日志'
    return '{}日志'.format(log_name.split('.')[0])