package com.njcn.csharmonic.offline.log;

import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csharmonic.offline.log.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class Log {
    private static String logPath = "C:\\Users\\Administrator\\Desktop\\浙江无线\\离线数据上传\\09\\log";//事件文件路径

    private static List<TagComtradeCfg> tagComtradeCfgs = new ArrayList();//波形文件cfg信息队列
    public static void main(String[] args) throws Exception {
        boolean logbin = false;
        File log = new File(logPath);
        if (log.isDirectory()) {
            File[] files = log.listFiles();
            for (File file : files) {
                convertLog(file);
                logbin = true;
            }
        }
        if (!logbin) {
            System.out.println("----------事件文件不存在----------");
        }
    }

    //事件参数文件解析
    public static List<NewTaglogbuffer> convertLog(File file) throws Exception {
        InputStream binFile = new FileInputStream(file);
        List<NewTaglogbuffer> newTaglogbuffers = new ArrayList<>();//事件队列
        //转换为byte[]
        if (binFile.available() == 0) {
            log.warn("文件：{}长度为0字节，程序将跳过本文件的转换",file.getName());
            binFile.close();
            return newTaglogbuffers;
        }
        long nBufSize = binFile.available(); //计算需要解析的文件总长
        int logLen = 28; //NewHeadTaglogbuffer大小 由于结构固定所这边直接写死28字节
        int n1BufLen = logLen + 4 * 8; //单个固定结构大小
        int nEventNum = (int) (nBufSize / n1BufLen); //确认共多少事件数据结构
        try {
            for (int i = 0; i < nEventNum; i++) {
                byte[] bBuf = new byte[n1BufLen]; //单个统计结构
                try {
                    binFile.read(bBuf, 0, bBuf.length);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new BusinessException("文件" + file.getName() + " 读取时发生错误");
                }
                LocalDateTime event_starttime = null;
                LocalDateTime event_endtime = null;
                NewTaglogbuffer newTaglogbuffer = getnewTaglogbuffer(bBuf);
                newTaglogbuffers.add(newTaglogbuffer);
                TagMsTime devtime = newTaglogbuffer.getNewHeadTaglogbuffer().getDevtime();
                LocalDateTime time = LocalDateTime.of(devtime.getYear(), devtime.getMonth(), devtime.getDay(), devtime.getHour(), devtime.getMin(), devtime.getSec(), devtime.getMs()*1000*1000);
                //存在启动时间
                if (event_starttime != LocalDateTime.MIN&& event_starttime!=null) {
                    if (time.compareTo(event_starttime) <= 0) {
                        event_starttime = time;
                    }
                } else {
                    //不存在启动时间 填入当前时间
                    event_starttime = time;
                }
                if (event_endtime != LocalDateTime.MIN && event_endtime!=null) {
                    if (time.compareTo(event_endtime) >= 0) {
                        event_endtime = time;
                    }
                } else {
                    //不存在结束时间 填入当前时间
                    event_endtime = time;
                }


                long sec = 0;
                for (NewBodyTaglogbuffer sing : newTaglogbuffer.getNewBodyTaglogbuffers()) {
                    switch (sing.getParaCode()) {
                        case 0: //特征幅值
                            //fParam2 = sing.ParaValue / 65536.0f;
                            break;
                        case 1: //持续时间
                            sec = sing.getParaValue() / 65536L;
                            break;
                        case 5: //相别
                            break;
                        case 25: //浮动门槛值
                            //fParam3 = sing.ParaValue / 65536.0f;
                            break;
                        default:
                            break;
                    }
                }
                //当事件时长超过1分钟直接排除
                if(sec>60){
                    continue;
                }
                newTaglogbuffer.setStart(time); //事件开始时间
                newTaglogbuffer.setEnd(time.plusSeconds(sec)); //事件结束时间
                //这里tagComtradeCfgs为空无效
//                for (TagComtradeCfg sing : tagComtradeCfgs) {
//                    if (sing.getTimeTrigger().compareTo(newTaglogbuffer.getStart()) <= 0 && sing.getTimeEnd().compareTo(newTaglogbuffer.getStart()) >= 0) {
//                        newTaglogbuffer.setPath(sing.getPath());
//                        break;
//                    }
//                }
            }
        } catch (BusinessException e) {
            e.printStackTrace();
            throw new BusinessException("文件" + file.getName() + " 解析失败");
        }finally {
            binFile.close();
        }
        return newTaglogbuffers;
    }

    //事件参数文件解析
    public static List<NewTaglogbuffer> convertLog(MultipartFile file) throws Exception {
        InputStream binFile = file.getInputStream();
        List<NewTaglogbuffer> newTaglogbuffers = new ArrayList<>();//事件队列
        //转换为byte[]
        if (binFile.available() == 0) {
            log.warn("文件：{}长度为0字节，程序将跳过本文件的转换",file.getOriginalFilename());
            binFile.close();
            return newTaglogbuffers;
        }
        long nBufSize = binFile.available(); //计算需要解析的文件总长
        int logLen = 28; //NewHeadTaglogbuffer大小 由于结构固定所这边直接写死28字节
        int n1BufLen = logLen + 4 * 8; //单个固定结构大小
        int nEventNum = (int) (nBufSize / n1BufLen); //确认共多少事件数据结构
        try {
            for (int i = 0; i < nEventNum; i++) {
                byte[] bBuf = new byte[n1BufLen]; //单个统计结构
                try {
                    binFile.read(bBuf, 0, bBuf.length);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new BusinessException("文件" + file.getOriginalFilename() + " 读取时发生错误");
                }
                NewTaglogbuffer newTaglogbuffer = getnewTaglogbuffer(bBuf);
                LocalDateTime event_starttime = null;
                LocalDateTime event_endtime = null;
                TagMsTime devtime = newTaglogbuffer.getNewHeadTaglogbuffer().getDevtime();
                LocalDateTime time = LocalDateTime.of(devtime.getYear(), devtime.getMonth(), devtime.getDay(), devtime.getHour(), devtime.getMin(), devtime.getSec(), devtime.getMs()*1000*1000);
                //存在启动时间
                if (event_starttime != LocalDateTime.MIN&& event_starttime!=null) {
                    if (time.compareTo(event_starttime) <= 0) {
                        event_starttime = time;
                    }
                } else {
                    //不存在启动时间 填入当前时间
                    event_starttime = time;
                }
                if (event_endtime != LocalDateTime.MIN && event_endtime!=null) {
                    if (time.compareTo(event_endtime) >= 0) {
                        event_endtime = time;
                    }
                } else {
                    //不存在结束时间 填入当前时间
                    event_endtime = time;
                }

                long sec = 0;
                for (NewBodyTaglogbuffer sing : newTaglogbuffer.getNewBodyTaglogbuffers()) {
                    switch (sing.getParaCode()) {
                        case 0: //特征幅值
                            //fParam2 = sing.ParaValue / 65536.0f;
                            break;
                        case 1: //持续时间
                            sec = sing.getParaValue() / 65536L;
                            break;
                        case 5: //相别
                            break;
                        case 25: //浮动门槛值
                            //fParam3 = sing.ParaValue / 65536.0f;
                            break;
                        default:
                            break;
                    }
                }
                //当事件时长超过1分钟直接排除
                if(sec>60){
                    continue;
                }
                newTaglogbuffer.setStart(time); //事件开始时间
                newTaglogbuffer.setEnd(time.plusSeconds(sec)); //事件结束时间
                //这里tagComtradeCfgs为空无效
//                for (TagComtradeCfg sing : tagComtradeCfgs) {
//                    if (sing.getTimeTrigger().compareTo(newTaglogbuffer.getStart()) <= 0 && sing.getTimeEnd().compareTo(newTaglogbuffer.getStart()) >= 0) {
//                        newTaglogbuffer.setPath(sing.getPath());
//                        break;
//                    }
//                }
                newTaglogbuffers.add(newTaglogbuffer);

            }
        } catch (BusinessException e) {
            e.printStackTrace();
            throw new BusinessException("文件" + file.getOriginalFilename() + " 解析失败");
        }finally {
            binFile.close();
        }
        return newTaglogbuffers;
    }

    private static NewTaglogbuffer getnewTaglogbuffer(byte[] data) {
        NewHeadTaglogbuffer head = getNewHeadTaglogbuffer(data);
        ArrayList<NewBodyTaglogbuffer> bodylist = getNewBodyTaglogbuffer(data, head);
        NewTaglogbuffer newTaglogbuffer = new NewTaglogbuffer(head, bodylist);
        return newTaglogbuffer;
    }

    private static NewHeadTaglogbuffer getNewHeadTaglogbuffer(byte[] data) {
        int structlen = 28;
        byte[] buff = new byte[structlen];
        System.arraycopy(data, 0, buff, 0, structlen);
        for (int i = 0; i < 12 * 2; i += 2) {
            reversalBuff(buff, i, 2);
        }
        for (int i = 12 * 2; i < (12 * 2 + 1 * 4); i += 4) {
            reversalBuff(buff, i, 4);
        }
        //数据区转换为结构
        NewHeadTaglogbuffer logBuff = (NewHeadTaglogbuffer) bytesToStruct(buff, 0, 28, "NewHeadTaglogbuffer");
        return logBuff;
    }

    private static ArrayList<NewBodyTaglogbuffer> getNewBodyTaglogbuffer(byte[] data, NewHeadTaglogbuffer head) {
        ArrayList<NewBodyTaglogbuffer> newBodyTaglogbuffers = new ArrayList<NewBodyTaglogbuffer>();
        int structlen = 28;
        int bodylen = head.getLogParaNum() * 8;
        byte[] buff = new byte[bodylen];
        System.arraycopy(data, structlen, buff, 0, bodylen);
        for (int i = 0; i < bodylen; i += 4) {
            reversalBuff(buff, i, 4);
        }
        for (int i = 0; i < head.getLogParaNum(); i++) {
            NewBodyTaglogbuffer logBuff = (NewBodyTaglogbuffer) bytesToStruct(buff, (i * 8), 8, "NewBodyTaglogbuffer");
            newBodyTaglogbuffers.add(logBuff);
        }
        return newBodyTaglogbuffers;
    }

    private static boolean reversalBuff(byte[] buffer, int StartIndex, int bufflen) {
        //确保长度为偶数
        if (bufflen % 2 != 0){
            return false;
        }
        int halflen = bufflen / 2;
        byte[] temp = new byte[halflen];
        for (int i = 0; i < halflen; i++) {
            temp[i] = buffer[i + StartIndex];
            buffer[i + StartIndex] = buffer[bufflen + StartIndex - i - 1];
            buffer[bufflen + StartIndex - i - 1] = temp[i];
        }
        return true;
    }

    private static Object bytesToStruct(byte[] buf, int nStart, int len, String type) {
        if ("NewHeadTaglogbuffer".equals(type)) {
            TagMsTime tagMsTime = new TagMsTime(Service.convertInt16(buf, 2),
                    Service.convertInt16(buf, 4),Service.convertInt16(buf, 6),
                    Service.convertInt16(buf, 8),Service.convertInt16(buf, 10),
                    Service.convertInt16(buf, 12),Service.convertInt16(buf, 14)
            );
            NewHeadTaglogbuffer newHeadTaglogbuffer = new NewHeadTaglogbuffer(Service.convertInt16(buf, 0),
                    tagMsTime,Service.convertInt16(buf, 16),Service.convertInt16(buf, 18),
                    Service.convertInt16(buf, 20),Service.convertInt16(buf, 22),
                    Service.convertInt32(buf, 24));
            return newHeadTaglogbuffer;
        } else if ("NewBodyTaglogbuffer".equals(type)) {
            NewBodyTaglogbuffer newBodyTaglogbuffer = new NewBodyTaglogbuffer(Service.convertInt32(buf, nStart),Service.convertInt32(buf, nStart + 4));
            return newBodyTaglogbuffer;
        }
        return null;
    }

}
