package cn.wise.sc.energy.power.plant.business.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.wise.sc.energy.power.plant.business.bean.DataPower;
import cn.wise.sc.energy.power.plant.business.bean.TimeModelQuery;
import cn.wise.sc.energy.power.plant.business.domain.CharacterParamInfo;
import cn.wise.sc.energy.power.plant.business.domain.FrequencyQuery;
import cn.wise.sc.energy.power.plant.business.domain.Oscillogram;
import cn.wise.sc.energy.power.plant.business.domain.RowKeyMapper;
import cn.wise.sc.energy.power.plant.business.domain.UnitInfo;
import cn.wise.sc.energy.power.plant.business.domain.eum.TendencyStatus;
import cn.wise.sc.energy.power.plant.business.domain.vo.CharacterParamInfoVo;
import cn.wise.sc.energy.power.plant.business.domain.vo.EntityVo;
import cn.wise.sc.energy.power.plant.business.jna.WaveAnalysis;
import cn.wise.sc.energy.power.plant.business.opentsdb.OpentsdbOkHttpClient;
import cn.wise.sc.energy.power.plant.business.opentsdb.bean.QueryExt;
import cn.wise.sc.energy.power.plant.business.opentsdb.bean.QueryRequestExt;
import cn.wise.sc.energy.power.plant.business.repository.CharacterParamRepository;
import cn.wise.sc.energy.power.plant.business.repository.UnitInfoRepository;
import cn.wise.sc.energy.power.plant.business.service.ICharacterParamService;
import cn.wise.sc.energy.power.plant.common.core.bean.BaseResponse;
import cn.wise.sc.energy.power.plant.common.core.exception.ResponseEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Lists;
import com.spring4all.spring.boot.starter.hbase.api.HbaseTemplate;
import lombok.extern.slf4j.Slf4j;
import net.opentsdb.client.api.query.response.QueryResponse;
import net.opentsdb.client.bean.Aggregator;
import net.opentsdb.client.bean.QueryResult;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @description: 测点特征信息服务层实现
 * @author: qh
 * @create: 2020-07-14 16:37
 **/
@Slf4j
@Service
public class CharacterParamServiceImpl extends BaseServiceImpl<String, CharacterParamInfo> implements ICharacterParamService {

    final
    UnitInfoServiceImpl unitInfoService;
    final
    CharacterParamRepository characterParamRepository;
    final
    UnitInfoRepository unitInfoRepository;
    final
    HbaseTemplate hbaseTemplate;

    public CharacterParamServiceImpl(UnitInfoServiceImpl unitInfoService,
                                     CharacterParamRepository characterParamRepository,
                                     UnitInfoRepository unitInfoRepository,
                                     HbaseTemplate hbaseTemplate) {
        this.unitInfoService = unitInfoService;
        this.characterParamRepository = characterParamRepository;
        this.unitInfoRepository = unitInfoRepository;
        this.hbaseTemplate = hbaseTemplate;
    }

    @Override
    @Cacheable(value = "CHARACTER_PARAM_INFO", key = "#plantid")
    public List<CharacterParamInfo> list(String plantid) {

        return characterParamRepository.findAllByPlantId(plantid);

    }

    @Override
    public List<Object[]> count() {
        return characterParamRepository.countAlert();
    }

    @Override
    public List<EntityVo> getUnitAllCharacterParams(String unitNo) {

        ResponseEnum.LICENCE_NOT_FOUND.assertNotEmpty(unitNo);

        CharacterParamInfo characterParamInfo = new CharacterParamInfo();
        characterParamInfo.setUnitCodeId(unitNo);

        List<CharacterParamInfo> all = this.repository.findAll(Example.of(characterParamInfo));

        return buildCharacterVo(all);
    }

    @Override
    public BaseResponse<Map<String, Map<String, HashMap<Long, Number>>>> get3DCharacter(String deviceId, String fileName) {

        //1.找部件的号
        List<String> unitNames = splitFileName(fileName);
        if (unitNames.size() == 0) {
            return BaseResponse.errorMsg("3D测点文件名不正确!");
        }
        //条件查询部件  设别号和测点名
        List<UnitInfo> unitInfos = unitInfoRepository.findAll((root, query, criteriaBuilder) -> {

            Path<String> deviceIdPath = root.get("deviceId");
            Predicate equal = criteriaBuilder.equal(deviceIdPath, deviceId);
            return criteriaBuilder.and(criteriaBuilder.and(equal));
        });
        //2.根据部件获取所有测点
        List<CharacterParamInfo> list = characterParamRepository.findAll((Specification<CharacterParamInfo>) (root, query, criteriaBuilder) -> {

            Predicate or = criteriaBuilder.or();
            for (String likeUnitName : unitNames) {
                Path<String> cpNamePath = root.get("cpName");
                Predicate like = criteriaBuilder.like(cpNamePath, "%" + likeUnitName + "%");
                or = criteriaBuilder.or(or, like);
            }
            Path<Object> hasDeriveParam = root.get("hasDeriveParam");
            Predicate predicate = criteriaBuilder.notEqual(hasDeriveParam, 1);
            Path<String> deviceIdPath = root.get("deviceId");
            Predicate equal = criteriaBuilder.equal(deviceIdPath, deviceId);
            Predicate rts = criteriaBuilder.and(criteriaBuilder.and(equal));
            return criteriaBuilder.and(rts, or, predicate);
        });
        List<CharacterParamInfo> characterParamInfos = list.stream()
                .filter(arg -> arg.getIsDeriveParam() == 0)
                .limit(10)
                .collect(Collectors.toList());
        return BaseResponse.okData(buildResult(characterParamInfos, unitInfos, getOpenTSDB(characterParamInfos)));
    }

    @Override
    public List<CharacterParamInfoVo> getCharactersByUnitCodeIds(List<String> unitCodeIds) {

        List<CharacterParamInfo> characterParamInfos = characterParamRepository.findAll((root, query, criteriaBuilder) -> {

            Path<String> unitCodeIdPath = root.get("unitCodeId");
            CriteriaBuilder.In<String> in = criteriaBuilder.in(unitCodeIdPath);
            for (String unitCodeId : unitCodeIds) {
                in.value(unitCodeId);
            }
            return in;
        });
        List<CharacterParamInfoVo> rts = new ArrayList<>(characterParamInfos.size());
        characterParamInfos.forEach(arg -> rts.add((CharacterParamInfoVo) arg.toVo()));
        return rts;
    }

    @Override
    public List<CharacterParamInfo> getKKsCodeByDeviceAndCharacterName(String deviceId, String character) {

        return characterParamRepository.findAll((root, query, criteriaBuilder) -> {
            Path<String> deviceIdPath = root.get("deviceId");
            Predicate equal = criteriaBuilder.equal(deviceIdPath, deviceId);
            Path<String> cpName = root.get("cpName");
            Predicate like = criteriaBuilder.like(cpName, character);
            return criteriaBuilder.and(equal, like);
        });
    }

    @Override
    public Map<Long, Map<String, Number>> getRealTimeDataByKksCode(List<String> kksCodes, String start, String downSample) {
        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(kksCodes);
        //去数据库匹配测点
        List<CharacterParamInfo> characterParamInfos = characterParamRepository.findAll((Specification<CharacterParamInfo>) (root, query, criteriaBuilder) -> {
            Path<String> kkscodePath = root.get("kksCode");
            CriteriaBuilder.In<String> in = criteriaBuilder.in(kkscodePath);
            for (String kkscode : kksCodes) {
                in.value(kkscode);
            }
            return in;
        });
        QueryRequestExt queryRequestExt = QueryRequestExt.builder()
                .start(start)
                .build();
        //获取最后一条数据 然后根据这个查询

        for (CharacterParamInfo characterParamInfo : characterParamInfos) {
            QueryExt build = QueryExt.builder()
                    .aggregator(Aggregator.AVG)
                    .metric(characterParamInfo.getKksCode())
                    .build();
            if (StrUtil.isNotBlank(downSample)) {
                build.setDownsample(downSample);
            }
            queryRequestExt.addQuery(build);
        }
        QueryResponse response;
        try {
            response = OpentsdbOkHttpClient.query(queryRequestExt);
            //没有数据时
            if (response.getResults().size() == 0) {
                response = enterWhenItIsARind(characterParamInfos);
            }
        } catch (IOException | URISyntaxException e) {
            log.error("根据kksCode获取当前start时候下的实时数据失败!");
            response = enterWhenItIsARind(characterParamInfos);
        }
        Map<String, Number> data = cutOneDataAnd2Map(response.getResults(), characterParamInfos);
        Map<Long, Map<String, Number>> rts = new HashMap<>(1);
        //组装时间段 有添加假数据 所以不用判断是否为空
        Long time = response.getResults().get(0).getDps().keySet().iterator().next();
        rts.put(time, data);

        //取一条数据
        return rts;
    }

    @Override
    public QueryResponse getRealTimeDataByKksCode(List<String> kksCodes, String start, String end, String downSample) {
        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(kksCodes);
        //去数据库匹配测点
        List<CharacterParamInfo> characterParamInfos = characterParamRepository.findAll((Specification<CharacterParamInfo>) (root, query, criteriaBuilder) -> {
            Path<String> kkscodePath = root.get("kksCode");
            CriteriaBuilder.In<String> in = criteriaBuilder.in(kkscodePath);
            for (String kkscode : kksCodes) {
                in.value(kkscode);
            }
            return in;
        });
        QueryRequestExt queryRequestExt = QueryRequestExt.builder()
                .start(start)
                .end(end)
                .build();

        //获取最后一条数据 然后根据这个查询
        for (CharacterParamInfo characterParamInfo : characterParamInfos) {
            QueryExt build = QueryExt.builder()
                    .aggregator(Aggregator.AVG)
                    .metric(characterParamInfo.getKksCode())
                    .build();
            if (StrUtil.isNotBlank(downSample)) {
                build.setDownsample(downSample);
            }
            queryRequestExt.addQuery(build);
        }
        QueryResponse response;
        try {
            response = OpentsdbOkHttpClient.query(queryRequestExt);
            //没有数据时
            if (response.getResults().size() == 0) {
                response = enterWhenItIsARind(characterParamInfos);
            }
            return response;
        } catch (IOException | URISyntaxException e) {
            log.error("根据kksCode获取当前start时候下的实时数据失败!");
            response = enterWhenItIsARind(characterParamInfos);
            return response;
        }
    }

    @Override
    public Map<String, Number> getRealTimeDataPower(List<String> kksCodes, String start) {

        return null;
    }

    @Override
    public List<CharacterParamInfoVo> getCharacterByName(List<String> characterNames,
                                                         String plantCode,
                                                         String deviceId) {
        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(characterNames);

        List<CharacterParamInfo> characterParamInfos = characterParamRepository
                .findAll((root, query, criteriaBuilder) -> {
                    Path<String> cpname = root.get("cpName");
                    Predicate predicate = criteriaBuilder.or();
                    for (String characterName : characterNames) {
                        predicate = criteriaBuilder.or(predicate,
                                criteriaBuilder.like(cpname, "%" + characterName + "%"));
                    }
                    if (StrUtil.isNotBlank(deviceId)) {
                        Path<Object> deviceIdPath = root.get("deviceId");
                        Predicate equal = criteriaBuilder.equal(deviceIdPath, deviceId);
                        predicate = criteriaBuilder.and(criteriaBuilder.and(equal), predicate);
                    }
                    if (StrUtil.isNotBlank(plantCode)) {
                        Path<Object> plantIdPath = root.get("plantId");
                        Predicate equal = criteriaBuilder.equal(plantIdPath, plantCode);
                        predicate = criteriaBuilder.and(criteriaBuilder.and(equal), predicate);
                    }
                    return predicate;
                });
        List<CharacterParamInfoVo> rts = new ArrayList<>(characterParamInfos.size());
        for (CharacterParamInfo characterParamInfo : characterParamInfos) {
            rts.add((CharacterParamInfoVo) characterParamInfo.toVo());
        }
        return rts;
    }

    @Override
    public BaseResponse<DataPower> getTendency(List<String> keys,
                                               TimeModelQuery timeModelQuery,
                                               Integer status) {

        //去数据库匹配测点
        List<CharacterParamInfo> characterParamInfos = characterParamRepository
                .findAll((Specification<CharacterParamInfo>) (root, query, criteriaBuilder) -> {
                    Path<String> kkscodePath = root.get("kksCode");
                    CriteriaBuilder.In<String> in = criteriaBuilder.in(kkscodePath);
                    for (String kkscode : keys) {
                        in.value(kkscode);
                    }
                    return in;
                });
        //如果时间传0  默认取最后一条数据向前推1h
        if (timeModelQuery.getStart() == 0 || timeModelQuery.getEnd() == 0) {
            timeModelQuery.setStart(1597456800000L);
            timeModelQuery.setEnd(1597460400000L);

//            QueryLastRequest queryLastRequest = new QueryLastRequest();
//            LastDataPointQuery lastDataPointQuery = new LastDataPointQuery();
//            lastDataPointQuery.setMetric("C0A00101CFA01CBA00R002");
//            List<LastDataPointQuery> list = new ArrayList<>();
//            list.add(lastDataPointQuery);
//            queryLastRequest.setQueries(list);
//            QueryLastResponse queryLastResponse;
//            try {
//                queryLastResponse = OpentsdbOkHttpClient.queryLast(queryLastRequest);
//                //获取最后一条数据的时间
//                Long timestamp = queryLastResponse.getResults().get(0).getTimestamp();
//                //以这个时间向前推1h
//                timeModelQuery.setStart(timestamp - (24 * 60 * 60 * 1000));
//                timeModelQuery.setEnd(timestamp);
//            } catch (IOException | URISyntaxException e) {
//                e.printStackTrace();
//            }
        }

        QueryRequestExt queryRequestExt = QueryRequestExt.builder()
                .start(timeModelQuery.getStart() + "")
                .end(timeModelQuery.getEnd() + "")
                .build();
        for (CharacterParamInfo characterParamInfo : characterParamInfos) {
            QueryExt build = QueryExt.builder()
                    .aggregator(Aggregator.AVG)
                    .metric(characterParamInfo.getKksCode())
                    .build();
            //填充统计类型
            if (status != null && status != 0) {
                build.setDownsample(TendencyStatus.getDownSampleByCode(status));
            }
            queryRequestExt.addQuery(build);
        }
        QueryResponse response;
        try {
            response = OpentsdbOkHttpClient.query(queryRequestExt);
            if (response.getResults().size() == 0) {
                return BaseResponse.errorMsg("当前时间段没有数据!");
            }
        } catch (IOException | URISyntaxException e) {
            log.error("根据kksCode获取当前start时候下的实时数据失败!");
            return BaseResponse.errorMsg("OpenTSDB调用失败");
        }
        return BaseResponse.okData(buildDataPower(response.getResults(),
                characterParamInfos));
    }

    @Override
    public List<CharacterParamInfo> getByKksCodes(List<String> kksCodes) {

        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(kksCodes);

        //去数据库匹配测点
        return characterParamRepository.findAll((Specification<CharacterParamInfo>) (root, query, criteriaBuilder) -> {
            Path<String> kkscodePath = root.get("kksCode");
            CriteriaBuilder.In<String> in = criteriaBuilder.in(kkscodePath);
            for (String kkscode : kksCodes) {
                in.value(kkscode);
            }
            return in;
        });
    }

    @Override
    public String getFrequency(String toJSONString) {
        try {
            String a = WaveAnalysis.INSTANCE.WaveAnalysisModel(toJSONString);
            return a;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public Map<String, String> getOscillogram(List<String> kksCodes) throws IOException {

        final String tableName = "thermalpower-plant-wave-data";
        final String records = "records";
        final String data = "Data";
        final String tags = "tags";
        List<Oscillogram> oscillogramList = new ArrayList<>(kksCodes.size());
        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(kksCodes);
        List<String> rowKeys = new ArrayList<>(kksCodes.size());
        //拼接rowKey获取最新数据rowKey
        System.out.println("============rowKey=============");
        for (String kKSCode : kksCodes) {
            System.out.println(getRowKey(kKSCode));
            Oscillogram oscillogram = hbaseTemplate.get(tableName, getRowKey(kKSCode),
                    new RowKeyMapper());
            if (oscillogram != null) {
                oscillogramList.add(oscillogram);
            }
        }
        FrequencyQuery frequencyQuery = new FrequencyQuery();
        FrequencyQuery.Record record = new FrequencyQuery.Record();
        FrequencyQuery.DataOut dataOut = new FrequencyQuery.DataOut();
        frequencyQuery.setRecord(record);
        frequencyQuery.getRecord().setData(dataOut);
        frequencyQuery.getRecord().getData().setData(new ArrayList<>());
        for (Oscillogram oscillogram : oscillogramList) {
            frequencyQuery.setStartTime(oscillogram.getStart());
            frequencyQuery.setTimeSpan(oscillogram.getTimeSpan());
            FrequencyQuery.DataIn dataIn = new FrequencyQuery.DataIn();
            dataIn.setKKSCode(oscillogram.getKKsCode());
            dataIn.setData(oscillogram.getMapData());
            dataIn.setKeyPhaseOffset(oscillogram.getNoVersionKeyPhaseOffset());
            dataIn.setPeriod(oscillogram.getPeriod());
            dataOut.setDirection(0);
            dataOut.setGenerationFreq(oscillogram.getGenerationFreq());
            dataOut.setRecordFlag(oscillogram.getRecordFlag());
            dataOut.setPoleNum(oscillogram.getPoleNum());
            frequencyQuery.getRecord().getData().getData().add(dataIn);
        }

        String frequency = getFrequency(JSON.toJSONString(frequencyQuery));
        Map<String, String> rts = new HashMap<>(2);
        System.out.println();
        rts.put("oscillogram", JSON.toJSONString(oscillogramList));
        rts.put("frequency", frequency);

        System.out.println("============rowKey=============");
        System.out.println(JSON.toJSONString(rowKeys));
        return rts;
//
////==================================================================================================
        //添加过滤器  过滤名字中包含kkscode
//        List<Filter> filters = new ArrayList<>(kksCodes.size());
//        for (String kkscode : kksCodes) {
//            RowFilter filter = new RowFilter(CompareFilter.CompareOp.EQUAL
//                    , new SubstringComparator(StrUtil.swapCase(kkscode)));
//            filters.add(filter);
//        }
//
//        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE, filters);
//        Scan scanRow = new Scan();
//        scanRow.setFilter(filterList);
//        scanRow.addFamily(Bytes.toBytes("records"));
//        scanRow.setReversed(true);
//        scanRow.setBatch(50);
//        scanRow.setMaxResultSize(50);
//        scanRow.setTimeRange(1596252170L, System.currentTimeMillis());
//
//        Scan scanTags = new Scan();
//        scanTags.setFilter(filterList);
//        scanTags.addFamily(Bytes.toBytes("tags"));
//        scanTags.setReversed(true);
//        scanTags.setBatch(50);
//        scanTags.setMaxResultSize(50);
//        scanRow.setTimeRange(1596252170L, System.currentTimeMillis());
//        System.out.println("============get--start=================");
//        long start = System.currentTimeMillis();
//        OscillogramRowMapper oscillogramRowMapper = new OscillogramRowMapper();
//        List<Oscillogram> oscillograms = hbaseTemplate.find(tableName,
//                scanRow, oscillogramRowMapper);
//
//        OscillogramTagsMapper oscillogramRowMapper2 = new OscillogramTagsMapper();
//        List<Oscillogram> oscillogramsTags = hbaseTemplate.find(tableName,
//                scanTags, oscillogramRowMapper2);
//        long end = System.currentTimeMillis() - start;
//        System.out.println(end);
//
//        oscillogramsTags.forEach(opt -> oscillograms.forEach(arg -> {
//            if (opt.getRowKey().equals(arg.getRowKey())) {
//                arg.setTimeSpan(opt.getTimeSpan());
//                arg.setRecordFlag(opt.getRecordFlag());
//                arg.setGenerationFreq(opt.getGenerationFreq());
//                arg.setPoleNum(opt.getPoleNum());
//                arg.setPeriod(opt.getPeriod());
//            }
//        }));
//        //筛选最新的一条数据
//        List<CharacterParamInfo> characterParamInfos = this.getByKksCodes(kksCodes);
//        Map<String, Oscillogram> oscillogramLastMap = new HashMap<>(characterParamInfos.size());
//        for (Oscillogram oscillogram : oscillograms) {
//            characterParamInfos.forEach(arg -> {
//                String kKSCode = oscillogram.getKKsCode();
//                if (kKSCode.equals(arg.getKksCode())) {
//                    if (oscillogramLastMap.containsKey(kKSCode)) {
//                        //比较已存在的startTime大小
//                        if (oscillogramLastMap.get(kKSCode).getStart() < oscillogram.getStart()) {
//                            oscillogramLastMap.put(kKSCode, oscillogram);
//                        }
//                    } else {
//                        oscillogramLastMap.put(kKSCode, oscillogram);
//                    }
//                }
//            });
//        }
//        List<Oscillogram> oscillogramList = new ArrayList<>(oscillogramLastMap.size());
//        for (String key : oscillogramLastMap.keySet()) {
//            oscillogramList.add(oscillogramLastMap.get(key));
//        }
//
//        System.out.println("oscillograms长度：" + oscillograms.size());
//        System.out.println("oscillograms长度：" + oscillogramsTags.size());
//        System.out.println("oscillogramList长度：" + oscillogramList.size());
//        FrequencyQuery frequencyQuery = new FrequencyQuery();
//        FrequencyQuery.Record record = new FrequencyQuery.Record();
//        FrequencyQuery.DataOut dataOut = new FrequencyQuery.DataOut();
//        frequencyQuery.setRecord(record);
//        frequencyQuery.getRecord().setData(dataOut);
//        frequencyQuery.getRecord().getData().setData(new ArrayList<>());
//        for (Oscillogram oscillogram : oscillogramList) {
//            frequencyQuery.setStartTime(oscillogram.getStart());
//            frequencyQuery.setTimeSpan(oscillogram.getTimeSpan());
//            FrequencyQuery.DataIn dataIn = new FrequencyQuery.DataIn();
//            dataIn.setKKSCode(StrUtil.swapCase(oscillogram.getKKsCode()));
//            dataIn.setData(oscillogram.getMapData());
//            dataIn.setKeyPhaseOffset(oscillogram.getNoVersionKeyPhaseOffset());
//            dataIn.setPeriod(oscillogram.getPeriod());
//            dataOut.setDirection(0);
//            dataOut.setGenerationFreq(oscillogram.getGenerationFreq());
//            dataOut.setRecordFlag(oscillogram.getRecordFlag());
//            dataOut.setPoleNum(oscillogram.getPoleNum());
//            frequencyQuery.getRecord().getData().getData().add(dataIn);
//        }
//
//        System.out.println(JSON.toJSONString(frequencyQuery));
//
//        String frequency = getFrequency(JSON.toJSONString(frequencyQuery));
//        Map<String, String> rts = new HashMap<>(2);
//
//        rts.put("oscillogram", JSON.toJSONString(oscillogramList));
//        rts.put("frequency", frequency);
//
//        return rts;
    }

    @Override
    public String getFrequencyByUpload(MultipartFile file) {
        try {
            //将文件内容转成json
            InputStreamReader inputStreamReader = new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String s;
            int count = 0;
            List<String> kKSCodes = new ArrayList<>();
            Map<String, List<Float>> data = new HashMap<>();
            List<String> timeStr = new ArrayList<>();
            while ((s = bufferedReader.readLine()) != null) {
                String[] split = s.split("\t");
                if (count == 0) {
                    //count=0时 为标题行 解析kkscode 解析kkscode
                    for (int i = 1; i < split.length; i++) {
                        kKSCodes.add(split[i]);
                    }
                    //初始化data
                    for (String kKSCode : kKSCodes) {
                        data.put(kKSCode, new ArrayList<>());
                    }
                } else {
                    //存时间
                    timeStr.add(split[0]);
                    //count!=0时 为数据行 第一个为时间 后面为数据
                    for (int i = 1; i < split.length; i++) {
                        String kKSCode = kKSCodes.get(i - 1);
                        data.get(kKSCode).add(Float.parseFloat(split[i]));
                    }
                }
                count++;
            }
            bufferedReader.close();

            //拿到时间计算偏移量和起始时间
            DateTime startParse = DateUtil.parse(timeStr.get(0), "YYYY/MM/DD HH:mm:ss.SSS");
            long startTime = startParse.getTime();
            DateTime endParse = DateUtil.parse(timeStr.get(timeStr.size() - 1), "YYYY/MM/DD HH:mm:ss.SSS");
            long endTime = endParse.getTime();
            //毫秒转化成微秒
            long timeSpan = (endTime - startTime) * 1000;

            //封装频谱计算数据
            FrequencyQuery frequencyQuery = new FrequencyQuery();
            FrequencyQuery.Record record = new FrequencyQuery.Record();
            FrequencyQuery.DataOut dataOut = new FrequencyQuery.DataOut();
            frequencyQuery.setRecord(record);
            frequencyQuery.getRecord().setData(dataOut);
            frequencyQuery.getRecord().getData().setData(new ArrayList<>());
            frequencyQuery.setTimeSpan(timeSpan);
            frequencyQuery.setStartTime(startTime);
            for (String key : data.keySet()) {
                FrequencyQuery.DataIn dataIn = new FrequencyQuery.DataIn();
                dataIn.setKKSCode(key);
                dataIn.setData(data.get(key));
                dataIn.setKeyPhaseOffset(new ArrayList<>());
                dataIn.setPeriod(0);
                dataOut.setDirection(0);
                dataOut.setGenerationFreq(50);
                dataOut.setRecordFlag(0);
                dataOut.setPoleNum(600);
                frequencyQuery.getRecord().getData().getData().add(dataIn);
            }
            return getFrequency(JSON.toJSONString(frequencyQuery));
        } catch (Exception e) {
            e.printStackTrace();
            return "数据文件格式不对!";
        }
    }

    public static void main(String[] args) {
        String str = "时间\t1F定子上下线棒层间温度1A\t1F定子上下线棒层间温度2A";
        String[] split = str.split("\t");
        System.out.println(split[1]);
    }


    private DataPower buildDataPower(List<QueryResult> results,
                                     List<CharacterParamInfo> characterParamInfos) {

        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(results);
        DataPower dataPower = new DataPower();
        if (results.size() != 0) {
            QueryResult queryResult = results.get(0);
            queryResult.getDps().keySet().forEach(arg -> dataPower.getXAxis().add(arg));
        }
        for (QueryResult queryResult : results) {
            CharacterParamInfo characterParamInfo = characterParamInfos.stream()
                    .filter(arg -> arg.getKksCode().equals(queryResult.getMetric()))
                    .findFirst().get();

            String cpName = characterParamInfo.getCpName();
            DataPower.PowerPoints powerPoints = new DataPower.PowerPoints();
            dataPower.getDataList().add(powerPoints);
            powerPoints.setName(cpName);
            powerPoints.setKksCode(characterParamInfo.getKksCode());

            //关联报警点数
            CharacterParamInfo.Alert alert = buildAlert(characterParamInfo);
            powerPoints.setColor(JSON.toJSONString(alert, SerializerFeature.IgnoreNonFieldGetter));

            queryResult.getDps().keySet().forEach(arg ->
                    powerPoints.getValue().add(queryResult.getDps().get(arg).toString()));
            if (powerPoints.getValue().size() == 0) {
                powerPoints.getValue().add("0");
            }
            //todo 查询阈值 color中添加阈值集合
        }
        return dataPower;
    }

    /**
     * 获取存最新Data的RowKey数据的RowKey
     * 规则:kKSCode+kKSCode
     *
     * @param kKSCode kKSCode
     * @return rowKey
     */
    private String getRowKey(String kKSCode) {
        ResponseEnum.LICENCE_NOT_FOUND.assertNotEmpty(kKSCode);
        String substring = kKSCode.substring(kKSCode.length() - 1);
        return StrUtil.swapCase(substring + kKSCode);
    }

    /**
     * 拼装报警点
     *
     * @param characterParamInfo 测点参数
     * @return 报警点儿
     */
    private CharacterParamInfo.Alert buildAlert(CharacterParamInfo characterParamInfo) {

        ResponseEnum.LICENCE_NOT_FOUND.assertNotNull(characterParamInfo);
        CharacterParamInfo.Alert alert = new CharacterParamInfo.Alert();
        //一级报警是否生效
        if (characterParamInfo.getProtectRuleValid() == 1) {
            alert.setProtectRuleMinValue(characterParamInfo.getProtectRuleMinValue());
            alert.setProtectRuleMaxValue(characterParamInfo.getProtectRuleMaxValue());
            alert.setProtectRuleExclude(characterParamInfo.getProtectRuleExclude());
        }
        //二级报警是否是否生效
        if (characterParamInfo.getAlertRuleValid() == 1) {
            alert.setAlertRuleMinValue(characterParamInfo.getAlertRuleMinValue());
            alert.setAlertRuleMaxValue(characterParamInfo.getAlertRuleMaxValue());
            alert.setAlertRuleExclude(characterParamInfo.getAlertRuleExclude());
        }

        return alert;
    }

    private Map<String, Number> cutOneDataAnd2Map(List<QueryResult> results,
                                                  List<CharacterParamInfo> characterParamInfos) {
        ResponseEnum.COLLECTION_NOT_ILLEGAL.assertCollectionNotILLEGAL(results);
        for (QueryResult queryResult : results) {
            Set<Map.Entry<Long, Number>> entries = queryResult.getDps().entrySet();
            LinkedHashMap<Long, Number> newDps = new LinkedHashMap<>(1);
            if (entries.iterator().hasNext()) {
                Map.Entry<Long, Number> next = entries.iterator().next();
                newDps.put(next.getKey(), next.getValue());
            } else {
                newDps.put(1L, 0);
            }
            queryResult.setDps(newDps);
        }
        //将KKsCode转成cpName
        Map<String, Number> rts = new HashMap<>(results.size());
        for (QueryResult queryResult : results) {
            List<CharacterParamInfo> collect = characterParamInfos.stream().
                    filter(arg -> queryResult.getMetric().equals(arg.getKksCode()))
                    .collect(Collectors.toList());
            CharacterParamInfo characterParamInfo = collect.get(0);
            rts.put(characterParamInfo.getCpName(), queryResult.getDps()
                    .values().iterator().next());
        }
        return rts;
    }


    /**
     * 拆分测点文件名
     *
     * @param fileName 部件名 ","
     * @return List<String>
     */
    private List<String> splitFileName(String fileName) {
        ResponseEnum.LICENCE_NOT_FOUND.assertNotEmpty(fileName);
        String[] split = fileName.split(",");
        if (split.length == 0) {
            return new ArrayList<>();
        }
        return Lists.newArrayList(split);
    }

    private List<QueryResult> getOpenTSDB(final List<CharacterParamInfo> list) {
        //构建QueryRequestExt
        QueryRequestExt queryRequestExt = QueryRequestExt.builder()
                .start("1s-ago")
                .build();
        for (CharacterParamInfo characterParamInfo : list) {
            String kksCode = characterParamInfo.getKksCode();
            queryRequestExt.addQuery(QueryExt.builder()
                    .aggregator(Aggregator.AVG)
                    .metric(kksCode)
                    .build());
        }
        QueryResponse response;
        try {
            response = OpentsdbOkHttpClient.query(queryRequestExt);
            if (response.getResults().size() == 0) {
                response = enterWhenItIsARind(list);
            }
        } catch (IOException | URISyntaxException e) {
            //出错时模拟数据
            response = enterWhenItIsARind(list);
            log.error("OpenTSDB请求错误!");
        }
        ResponseEnum.LICENCE_NOT_FOUND.assertNotNull(response);
        return response.getResults();
    }

    private QueryResponse enterWhenItIsARind(List<CharacterParamInfo> list) {
        //出错时模拟数据
        QueryResponse response = new QueryResponse();
        response.setResults(new ArrayList<>());
        long currentTimeMillis = System.currentTimeMillis();
        for (CharacterParamInfo characterParamInfo : list) {
            QueryResult queryResult = new QueryResult();
            queryResult.setMetric(characterParamInfo.getKksCode());
            LinkedHashMap<Long, Number> map = new LinkedHashMap<>(1);
            map.put(currentTimeMillis, 0);
            queryResult.setDps(map);
            response.getResults().add(queryResult);
        }
        return response;
    }

    public Map<String, Map<String, HashMap<Long, Number>>> buildResult(
            final List<CharacterParamInfo> characters,
            final List<UnitInfo> unitInfos,
            final List<QueryResult> queryResults) {
        Map<String, Map<String, HashMap<Long, Number>>> rts = new HashMap<>(unitInfos.size());
        queryResults.forEach(arg -> characters.forEach(opt -> {
            if (arg.getMetric().equals(opt.getKksCode())) {
                unitInfos.forEach(pam -> {
                    if (pam.getUnitCodeId().equals(opt.getUnitCodeId())) {
                        String key = pam.getUnitName() + "|" + pam.getFunction();
                        if (!rts.containsKey(key)) {
                            Map<String, HashMap<Long, Number>> characterData = new HashMap<>();
                            rts.put(key, characterData);
                        }
                        rts.get(key).put(opt.getCpName(), arg.getDps() != null && arg.getDps().size() != 0 ?
                                arg.getDps() : new HashMap(1) {
                            {
                                put("1", 0);
                            }
                        });
                    }
                });
            }
        }));
        return rts;
    }

    private List<EntityVo> buildCharacterVo(List<CharacterParamInfo> characterParamInfos) {

        //获取父级特征值
        List<CharacterParamInfo> parents = characterParamInfos.stream()
                .filter(arg -> arg.getIsDeriveParam() == 0)
                .collect(Collectors.toList());
        List<EntityVo> rts = new ArrayList<>(parents.size());
        //获取子级特征值
        List<CharacterParamInfo> children = characterParamInfos.stream()
                .filter(arg -> arg.getIsDeriveParam() == 1)
                .collect(Collectors.toList());
        parents.forEach(arg -> {
            CharacterParamInfoVo characterParamInfoVoParent = new CharacterParamInfoVo();
            characterParamInfoVoParent.setChild(new ArrayList<>());
            BeanUtils.copyProperties(arg, characterParamInfoVoParent);
            children.forEach(opt -> {
                if (opt.getDerivedFrom().equals(arg.getKksCode())) {
                    CharacterParamInfoVo characterParamInfoVoChild = new CharacterParamInfoVo();
                    BeanUtils.copyProperties(opt, characterParamInfoVoChild);
                    characterParamInfoVoParent.getChild().add(characterParamInfoVoChild);
                }
            });
            rts.add(characterParamInfoVoParent);
        });
        return rts;
    }
}
