package com.jiayue.ssi.job;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.text.csv.CsvWriter;
import cn.hutool.core.util.CharsetUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiayue.ssi.constant.SecretKeyConstants;
import com.jiayue.ssi.entity.*;
import com.jiayue.ssi.entity.server.Jvm;
import com.jiayue.ssi.service.SysAlarmService;
import com.jiayue.ssi.service.SysLogininforService;
import com.jiayue.ssi.service.SysOperLogService;
import com.jiayue.ssi.service.SysPolicyService;
import com.jiayue.ssi.util.DateUtils;
import com.jiayue.ssi.util.FileUtil;
import com.jiayue.ssi.util.ResponseVO;
import com.jiayue.ssi.util.SM2CryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* 自动备份审计日志
*
* @author xsl
* @since 2023/04/06
*/
@Service
@EnableScheduling
@Slf4j
public class AutoAuditBak {
    @Autowired
    SysLogininforService sysLogininforService;
    @Autowired
    SysPolicyService sysPolicyService;
    @Autowired
    SysOperLogService sysOperLogService;


    /**
     * 每天凌晨1点执行
     */
    @Scheduled(cron = "15 0/5 * * * ?")
    public void auditBak() throws Exception{


        try {
            // 登录日志备份
            createSysLogininforCsvFile();
        }
        catch (Exception e){
            log.error("登录日志备份出错",e);
        }
        try {
            // 操作日志备份
            createSysOperCsvFile();
        }
        catch (Exception e){
            log.error("操作日志备份出错",e);
        }
    }


    public Calendar getYesterday(){
        Calendar calendar = Calendar.getInstance(); //创建Calendar 的实例
        //前一天开始的时间
        calendar.setTime(DateUtil.parse(DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd 00:00:00")));
        return calendar;
    }
    /**
     * 生成登录日志csv文件
     *
     */
    public void createSysLogininforCsvFile() throws Exception{
        Calendar calendar = getYesterday();
        QueryWrapper<SysLogininfor> sysLogininforQueryWrapper = new QueryWrapper<>();
        sysLogininforQueryWrapper.ge("create_time", calendar.getTime());
        // 备份文件名
        String fileName = DateUtil.format(calendar.getTime(),"yyyy-MM-dd") + "-" + "SysLogininfor" + ".csv";
        calendar.add(Calendar.DAY_OF_MONTH,1);
        sysLogininforQueryWrapper.lt("create_time",calendar.getTime() );
        List<SysLogininfor> sysLogininforList = sysLogininforService.list(sysLogininforQueryWrapper);
        // 生成csv备份
        if (sysLogininforList.size()>0){

            //第一行
            String[] listName = new String[15];
            listName[0] = "infoId";
            listName[1] = "userName";
            listName[2] = "status";
            listName[3] = "ipaddr";
            listName[4] = "loginLocation";
            listName[5] = "browser";
            listName[6] = "os";
            listName[7] = "msg";
            listName[8] = "loginTime";
            listName[9] = "delFlag";
            listName[10] = "createBy";
            listName[11] = "createTime";
            listName[12] = "updateBy";
            listName[13] = "updateTime";
            listName[14] = "remark";
            //获取String[]类型的数据至result中
            List<String> result = new ArrayList<>();
            String listNameStr = "";
            for (int i=0;i<listName.length;i++){
                listNameStr = listNameStr + listName[i]+"|";
            }
//            String headEncrypt = SM2CryptUtils.encrypt(listNameStr.substring(0,listNameStr.length()-1), SecretKeyConstants.SERVER_PUBLIC_KEY);
//            System.out.println("加密："+headEncrypt);
//            String headText = SM2CryptUtils.decrypt(headEncrypt,SecretKeyConstants.CLIENT_PRIVATE_KEY);
//            System.out.println("解密："+headText);
            //将listName添加到result中
            result.add(listNameStr.substring(0,listNameStr.length()-1));
            Long delIds[] = new Long[sysLogininforList.size()];
            for (int j=0;j<sysLogininforList.size();j++) {
                SysLogininfor sysLogininfor = sysLogininforList.get(j);
                String[] listValue = new String[15];
                listValue[0] = String.valueOf(sysLogininfor.getInfoId());
                delIds[j] = sysLogininfor.getInfoId();
                listValue[1] = String.valueOf(sysLogininfor.getUserName());
                listValue[2] = String.valueOf(sysLogininfor.getStatus());
                listValue[3] = String.valueOf(sysLogininfor.getIpaddr());
                listValue[4] = String.valueOf(sysLogininfor.getLoginLocation());
                listValue[5] = String.valueOf(sysLogininfor.getBrowser());
                listValue[6] = String.valueOf(sysLogininfor.getOs());
                listValue[7] = String.valueOf(sysLogininfor.getMsg());
                listValue[8] = String.valueOf(DateUtil.format(sysLogininfor.getLoginTime(),"yyyy-MM-dd HH:mm:ss"));
                listValue[9] = String.valueOf(sysLogininfor.getDelFlag());
                listValue[10] = String.valueOf(sysLogininfor.getCreateBy());
                listValue[11] = String.valueOf(DateUtil.format(sysLogininfor.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
                listValue[12] = String.valueOf(sysLogininfor.getUpdateBy());
                listValue[13] = String.valueOf(DateUtil.format(sysLogininfor.getUpdateTime(),"yyyy-MM-dd HH:mm:ss"));
                listValue[14] = String.valueOf(sysLogininfor.getRemark());

                String listValueStr = "";
                for (int k=0;k<listValue.length;k++){
                    listValueStr = listValueStr + listValue[k]+"|";
                }
//                String encrypt = SM2CryptUtils.encrypt(listValueStr.substring(0,listValueStr.length()-1), SecretKeyConstants.SERVER_PUBLIC_KEY);
//                System.out.println("加密："+encrypt);
//                String text = SM2CryptUtils.decrypt(encrypt,SecretKeyConstants.CLIENT_PRIVATE_KEY);
//                System.out.println("解密："+text);
                result.add(listValueStr.substring(0,listValueStr.length()-1));
            }
            //导入HuTool中CSV工具包的CsvWriter类
            //设置导出字符类型, CHARSET_UTF_8
            File csvFile = new File(fileName);
            File destDir = new File(FileUtil.getAuditBackUpPath()+ File.separator +DateUtils.dateTime());
            if (!destDir.exists()) {// 如果目录不存在则创建目录
                boolean b = destDir.mkdirs();
                if (!b) {
                    throw new RuntimeException(destDir.getPath() + " 目录创建失败");
                }
            }
            CsvWriter writer = CsvUtil.getWriter(destDir + File.separator + csvFile.getName(), CharsetUtil.CHARSET_UTF_8);
            writer.write(result);  //通过CsvWriter中的write方法写入数据
            writer.close();   //关闭CsvWriter
        }
        log.info("执行登录日志备份:{}",calendar.getTime());
    }

    /**
     * 生成操作日志csv文件
     *
     */
    public void createSysOperCsvFile() throws Exception{
        Calendar calendar = getYesterday();
        QueryWrapper<SysOperLog> sysOperLogQueryWrapper = new QueryWrapper<>();
        sysOperLogQueryWrapper.ge("create_time", calendar.getTime());
        // 备份文件名
        String fileName = DateUtil.format(calendar.getTime(),"yyyy-MM-dd") + "-" + "SysOperLog" + ".csv";
        calendar.add(Calendar.DAY_OF_MONTH,1);
        sysOperLogQueryWrapper.lt("create_time",calendar.getTime() );
        List<SysOperLog> sysOperLogList = sysOperLogService.list(sysOperLogQueryWrapper);
        // 生成csv备份
        if (sysOperLogList.size()>0){

            //第一行
            String[] listName = new String[25];
            listName[0] = "operId";
            listName[1] = "title";
            listName[2] = "businessType";
            listName[3] = "auditType";
            listName[4] = "businessTypes";
            listName[5] = "method";
            listName[6] = "requestMethod";
            listName[7] = "operatorType";
            listName[8] = "operName";
            listName[9] = "deptName";
            listName[10] = "operUrl";
            listName[11] = "operIp";
            listName[12] = "operLocation";
            listName[13] = "operParam";
//            listName[14] = "jsonResult";
            listName[14] = "status";
            listName[15] = "errorMsg";
            listName[16] = "operTime";
            listName[17] = "costTime";
            listName[18] = "delFlag";
            listName[19] = "createBy";
            listName[20] = "createTime";
            listName[21] = "updateBy";
            listName[22] = "updateTime";
            listName[23] = "remark";
            //获取String[]类型的数据至result中
            List<String> result = new ArrayList<>();
            String listNameStr = "";
            for (int i=0;i<listName.length;i++){
                listNameStr = listNameStr + listName[i]+"|";
            }
//            String headEncrypt = SM2CryptUtils.encrypt(listNameStr.substring(0,listNameStr.length()-1), SecretKeyConstants.CLIENT_PUBLIC_KEY);
//            System.out.println("加密："+headEncrypt);
//            String headText = SM2CryptUtils.decrypt(headEncrypt,SecretKeyConstants.CLIENT_PRIVATE_KEY);
//            System.out.println("解密："+headText);
            //将listName添加到result中
            result.add(listNameStr.substring(0,listNameStr.length()-1));
            Long delIds[] = new Long[sysOperLogList.size()];
            for (int j=0;j<sysOperLogList.size();j++) {
                SysOperLog sysOperLog = sysOperLogList.get(j);
                String[] listValue = new String[25];
                listValue[0] = String.valueOf(sysOperLog.getOperId());
                delIds[j] = sysOperLog.getOperId();
                listValue[1] = String.valueOf(sysOperLog.getTitle());
                listValue[2] = String.valueOf(sysOperLog.getBusinessType());
                listValue[3] = String.valueOf(sysOperLog.getAuditType());
                listValue[4] = String.valueOf(sysOperLog.getBusinessTypes());
                listValue[5] = String.valueOf(sysOperLog.getMethod());
                listValue[6] = String.valueOf(sysOperLog.getRequestMethod());
                listValue[7] = String.valueOf(sysOperLog.getOperatorType());
                listValue[8] = String.valueOf(sysOperLog.getOperName());
                listValue[9] = String.valueOf(sysOperLog.getDeptName());
                listValue[10] = String.valueOf(sysOperLog.getOperUrl());
                listValue[11] = String.valueOf(sysOperLog.getOperIp());
                listValue[12] = String.valueOf(sysOperLog.getOperLocation());
                listValue[13] = String.valueOf(sysOperLog.getOperParam());
//                listValue[14] = String.valueOf(sysOperLog.getJsonResult());
                listValue[14] = String.valueOf(sysOperLog.getStatus());
                listValue[15] = String.valueOf(sysOperLog.getErrorMsg());
                listValue[16] = String.valueOf(DateUtil.format(sysOperLog.getOperTime(),"yyyy-MM-dd HH:mm:ss"));
                listValue[17] = String.valueOf(sysOperLog.getCostTime());
                listValue[18] = String.valueOf(sysOperLog.getDelFlag());
                listValue[19] = String.valueOf(sysOperLog.getCreateBy());
                listValue[20] = String.valueOf(DateUtil.format(sysOperLog.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
                listValue[21] = String.valueOf(sysOperLog.getUpdateBy());
                listValue[22] = String.valueOf(DateUtil.format(sysOperLog.getUpdateTime(),"yyyy-MM-dd HH:mm:ss"));
                listValue[23] = String.valueOf(sysOperLog.getRemark());

                String listValueStr = "";
                for (int k=0;k<listValue.length;k++){
                    listValueStr = listValueStr + listValue[k]+"|";
                }
//                String encrypt = SM2CryptUtils.encrypt(listValueStr.substring(0,listValueStr.length()-1), SecretKeyConstants.CLIENT_PUBLIC_KEY);
//                System.out.println("加密："+encrypt);
//                String text = SM2CryptUtils.decrypt(encrypt,SecretKeyConstants.CLIENT_PRIVATE_KEY);
//                System.out.println("解密："+text);
                result.add(listValueStr.substring(0,listValueStr.length()-1));
            }
            //导入HuTool中CSV工具包的CsvWriter类
            //设置导出字符类型, CHARSET_UTF_8
            File csvFile = new File(fileName);
            File destDir = new File(FileUtil.getAuditBackUpPath()+ File.separator +DateUtils.dateTime());
            if (!destDir.exists()) {// 如果目录不存在则创建目录
                boolean b = destDir.mkdirs();
                if (!b) {
                    throw new RuntimeException(destDir.getPath() + " 目录创建失败");
                }
            }
            CsvWriter writer = CsvUtil.getWriter(destDir + File.separator + csvFile.getName(), CharsetUtil.CHARSET_UTF_8);
            writer.write(result);  //通过CsvWriter中的write方法写入数据
            writer.close();   //关闭CsvWriter
        }
        log.info("执行操作日志备份:{}",calendar.getTime());
    }
}
