package com.huatek.busi.service.impl.dataoutput.helper;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.LocalDate;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import com.huatek.busi.dto.SimulateResultDto;
import com.huatek.busi.init.SftpInit;
import com.huatek.busi.service.ILabReportBasisDataService;
import com.huatek.busi.service.dataoutput.DataOutputSimulateExecutor;
import com.huatek.busi.service.dataoutput.DataOutputWarningExecutor;
import com.huatek.busi.vo.warning.BusiEqmWarningTaskVo;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.huatek.busi.service.dataoutput.DataOutputExecutor;
import com.huatek.busi.vo.dataoutput.OutputEquipmentVo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * 数据输出工具类方法
 *
 * @author anker_cheng
 * @date 2019/10/14
 */
@Slf4j
@Component("dataOutputExecutors")
public class DataOutputExecutors implements ApplicationContextAware {
    private final Joiner joiner = Joiner.on("").skipNulls();
    /** 实现类缓存 */
    private final Map<String, DataOutputExecutor> IMPLS = Maps.newConcurrentMap();

    /** 实现类缓存 */
    private final Map<String, DataOutputSimulateExecutor> IMPLSS = Maps.newConcurrentMap();

    /** 实现类缓存 */
    private final Map<String, DataOutputWarningExecutor> IMPLSW = Maps.newConcurrentMap();


    @Resource
    private SftpInit sftpInit;

    @Value("${simulate.base.path}")
    private String baseFTP;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        Map<String, DataOutputExecutor> beansOfTypeMap = applicationContext.getBeansOfType(DataOutputExecutor.class);
//        if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) {
//            return;
//        }
//        for (Entry<String, DataOutputExecutor> entry : beansOfTypeMap.entrySet()) {
//            OptExecutor[] annotations =
//                AopUtils.getTargetClass(entry.getValue()).getAnnotationsByType(OptExecutor.class);
//            if (annotations == null || annotations.length == 0) {
//                continue;
//            }
//            for (OptExecutor annotation : annotations) {
//                String key = joiner.join(annotation.mainEquipmentType(), annotation.subEquipmentType());
//                if (IMPLS.containsKey(key)) {
//                    log.error("实现类已经存在：{}", key);
//                    continue;
//                }
//                DataOutputExecutor executor = entry.getValue();
//                log.debug("数据输出实现类：{}-{}-{}", annotation.mainEquipmentType(), annotation.subEquipmentType(), executor);
//                IMPLS.put(key, executor);
//            }
//        }
        this.buildDataOutputExecutor(applicationContext);
        this.buildSimulateExecutors(applicationContext);
        this.buildWarningEqmExecutors(applicationContext);
    }


    public void buildDataOutputExecutor(ApplicationContext applicationContext) throws BeansException {
        Map<String, DataOutputExecutor> beansOfTypeMap = applicationContext.getBeansOfType(DataOutputExecutor.class);
        if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) {
            return;
        }
        for (Entry<String, DataOutputExecutor> entry : beansOfTypeMap.entrySet()) {
            OptExecutor[] annotations =
                    AopUtils.getTargetClass(entry.getValue()).getAnnotationsByType(OptExecutor.class);
            if (annotations == null || annotations.length == 0) {
                continue;
            }
            for (OptExecutor annotation : annotations) {
                String key = joiner.join(annotation.mainEquipmentType(), annotation.subEquipmentType());
                if (IMPLS.containsKey(key)) {
                    log.error("实现类已经存在：{}", key);
                    continue;
                }
                DataOutputExecutor executor = entry.getValue();
                log.debug("数据输出实现类：{}-{}-{}", annotation.mainEquipmentType(), annotation.subEquipmentType(), executor);
                IMPLS.put(key, executor);
            }
        }
    }

    public void buildSimulateExecutors(ApplicationContext applicationContext) throws BeansException {
        Map<String, DataOutputSimulateExecutor> beansOfTypeMap = applicationContext.getBeansOfType(DataOutputSimulateExecutor.class);
        if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) {
            return;
        }
        for (Entry<String, DataOutputSimulateExecutor> entry : beansOfTypeMap.entrySet()) {
            OptSimulatExecutor[] annotations =
                    AopUtils.getTargetClass(entry.getValue()).getAnnotationsByType(OptSimulatExecutor.class);
            if (annotations == null || annotations.length == 0) {
                continue;
            }
            for (OptSimulatExecutor annotation : annotations) {
                String key = joiner.join(annotation.pId(), annotation.equipmentType());
                if (IMPLS.containsKey(key)) {
                    log.error("实现类已经存在：{}", key);
                    continue;
                }
                DataOutputSimulateExecutor executor = entry.getValue();
                log.debug("数据输出实现类：{}-{}-{}", annotation.pId(), annotation.equipmentType(), executor);
                IMPLSS.put(key, executor);
            }
        }
    }


    public void buildWarningEqmExecutors(ApplicationContext applicationContext) throws BeansException {
        Map<String, DataOutputWarningExecutor> beansOfTypeMap = applicationContext.getBeansOfType(DataOutputWarningExecutor.class);
        if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) {
            return;
        }
        for (Entry<String, DataOutputWarningExecutor> entry : beansOfTypeMap.entrySet()) {
            OptWarningEqmExecutor[] annotations =
                    AopUtils.getTargetClass(entry.getValue()).getAnnotationsByType(OptWarningEqmExecutor.class);
            if (annotations == null || annotations.length == 0) {
                continue;
            }
            for (OptWarningEqmExecutor annotation : annotations) {
                String key = joiner.join(annotation.eqType(), annotation.gzType());
                if (IMPLSW.containsKey(key)) {
                    log.error("实现类已经存在：{}", key);
                    continue;
                }
                DataOutputWarningExecutor executor = entry.getValue();
                log.debug("数据输出实现类：{}-{}-{}", annotation.eqType(), annotation.gzType(), executor);
                IMPLSW.put(key, executor);
            }
        }
    }


    private DataOutputExecutor impl(String mainEquipmentType, String subEquipmentType) {
        DataOutputExecutor executor = IMPLS.get(joiner.join(mainEquipmentType, subEquipmentType));
        return executor;
    }


    private DataOutputSimulateExecutor implSimulate(String pId,String equipmentType){
        DataOutputSimulateExecutor executor =  IMPLSS.get(joiner.join(pId,equipmentType));
        return executor;
    }
    private DataOutputWarningExecutor implWarning(String eqType, String gzType) {
        DataOutputWarningExecutor executor =  IMPLSW.get(joiner.join(eqType,gzType));
        return executor;
    }

    public void doOutput(String basePath, String filePath, String fileName, OutputEquipmentVo vo, LocalDate day)
        throws Exception {
        // 创建文件
        Path path = DataOutputUtil.createFile(basePath, filePath, fileName);
        // 获取实现类，写文件
        DataOutputExecutor executor = impl(vo.getMainEquipmentType(), vo.getEquipmentType());
        if (executor == null) {
            log.warn("找不到实现类：{}-{}", vo.getMainEquipmentType(), vo.getEquipmentType());
            return;
        }
            executor.execute(path, vo, day);
    }

    public void doOutputSimulate(String basePath, String filePath, String fileName, SimulateResultDto vo, LocalDate day)
            throws Exception {
        // 创建文件
        Path path = DataOutputUtil.createFile(basePath, filePath, fileName);

        // 获取实现类，写文件
        DataOutputSimulateExecutor executor = implSimulate(vo.getPId(),vo.getEquipmentType());

        if (executor == null) {
            log.warn("找不到实现类：{}-{}", vo.getPId(),vo.getEquipmentType());
            return;
        }
        executor.execute(path,vo,day,fileName);


    }

    public void doOutputWarning(String basePath, String filePath, String fileName, BusiEqmWarningTaskVo vo, LocalDate day) throws Exception {
        // 创建文件
        Path path = DataOutputUtil.createFile(basePath, filePath, fileName);

        // 获取实现类，写文件
        DataOutputWarningExecutor executor = implWarning(vo.getEqType(),vo.getGzType());

        if (executor == null) {
            log.warn("找不到实现类：{}-{}", vo.getEqType(),vo.getGzType());
            return;
        }
        executor.execute(path,vo,day,fileName);
    }


}
