package com.ningdatech.pmapi.scheduler.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.log.mapper.OptLogMapper;
import com.ningdatech.log.model.domain.OptLog;
import com.ningdatech.pmapi.organization.mapper.DingEmployeeInfoMapper;
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo;
import com.ningdatech.pmapi.scheduler.task.model.CommonLog;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 通用日志写入任务
 * @author liushuai
 */
@Component
@RequiredArgsConstructor
public class CommonLogTask {
    private final OptLogMapper optLogMapper;
    private final IUserInfoService userInfoService;
    private final DingEmployeeInfoMapper dingEmployeeInfoMapper;
    /**
     * 日志记录文件位置
     */
    private final static String LOG_RECORD_ADDRESS = "/opt/log/";
    private final static String LOG_ID_FILE = "logId.txt";
    private final static String LOG_FILE = "common_log_";

    @Value("${hostname}")
    private String HOST_NAME;

    @Scheduled(fixedDelay = 120000)
    public void writeLog() throws UnknownHostException {
        //
        if (!HOST_NAME.equals(InetAddress.getLocalHost().getHostName())) {
            return;
        }
        //获取记录ID文件
        boolean idFileExist = FileUtil.exist(LOG_RECORD_ADDRESS + LOG_ID_FILE);
        if (!idFileExist){
            FileUtil.touch(LOG_RECORD_ADDRESS + LOG_ID_FILE);
        }
        FileReader fileReader = new FileReader(LOG_RECORD_ADDRESS + LOG_ID_FILE);
        String result = fileReader.readString();
        long startLogId = 0L;
        if (StringUtils.isNotBlank(result)){
            startLogId = Long.parseLong(result);
        }
        LambdaQueryWrapper<OptLog> query = Wrappers.lambdaQuery(OptLog.class).gt(OptLog::getId,startLogId);
        //查询日志
        List<OptLog> logList = optLogMapper.selectList(query);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (CollectionUtil.isNotEmpty(logList)){
           for (OptLog optLog : logList){
               CommonLog commonLog = new CommonLog();
               UserInfo userInfo = userInfoService.getById(optLog.getCreateBy());
               if (userInfo == null){
                   continue;
               }
               String employeeCode = userInfo.getEmployeeCode();
               if (StringUtils.isNotBlank(employeeCode)){
                   DingEmployeeInfo dingEmployeeInfo = dingEmployeeInfoMapper.selectOne(new LambdaQueryWrapper<DingEmployeeInfo>()
                           .eq(DingEmployeeInfo::getEmployeeCode,employeeCode));
                   if (dingEmployeeInfo != null){
                       commonLog.setUserId(String.valueOf(dingEmployeeInfo.getAccountId()));
                   }
               }else {
                   commonLog.setUserId(String.valueOf(userInfo.getId()));
               }
               commonLog.setUserRole("政府工作人员");
               commonLog.setAreaCode(userInfo.getRegionCode());
               String description = optLog.getDescription();
               if ("用户登录".equals(description)){
                   commonLog.setActionType(1);
               }else if (description.contains("退出登录")){
                   commonLog.setActionType(2);
               }else {
                   commonLog.setActionType(3);
               }
               String actionId = UUID.randomUUID().toString();
               commonLog.setActionId(actionId);
               commonLog.setActionTime(df.format(optLog.getStartTime()));
               commonLog.setActionDuration(optLog.getConsumingTime());
               commonLog.setActionStatus(0);
               commonLog.setAppCode("A331101453557202109017383");
               //判断当天日志文件是否存在
               DateTimeFormatter dfNow = DateTimeFormatter.ofPattern("yyyyMMdd");
               String fileName = LOG_RECORD_ADDRESS + LOG_FILE + dfNow.format(LocalDateTime.now()) + ".log";
               boolean fileExist = FileUtil.exist(fileName);
               if (!fileExist){
                   //不存在则创建当天日志文件
                   FileUtil.touch(fileName);
               }
               //写入通用规则
               FileWriter writer = new FileWriter(fileName);
               writer.append(JSONUtil.toJsonStr(commonLog));
               writer.append("\n");
               if (commonLog.getActionType() == 3){
                   CommonLog commonLogEnd = new CommonLog();
                   BeanUtil.copyProperties(commonLog,commonLogEnd);
                   commonLogEnd.setActionType(4);
                   writer.append(JSONUtil.toJsonStr(commonLogEnd));
                   writer.append("\n");
               }
           }
            //记录最后一个节点位置
            FileWriter writer = new FileWriter(LOG_RECORD_ADDRESS + LOG_ID_FILE);
            writer.write(String.valueOf(logList.get(logList.size() - 1).getId()));
        }
    }
}
