package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbCollectDataJobService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbCollectDataRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbCollectDataStrategyService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesThirdPartyDbCollectDataRecord;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.SxThirdPartyDbCollectDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * @Author: wangjie
 * @CreateDate: 2019/8/23 1:16 PM
 * @Description: 第三方DB数据采集定时任务
 **/
@Slf4j
@Service
public class SxThirdPartyDbCollectDataJobService implements ISxThirdPartyDbCollectDataJobService {

    @Autowired
    private IConfigService configService;

    @Autowired
    private ISxThirdPartyDbCollectDataRecordService thirdPartyDbCollectDataRecordService;

    @Value("${spring.jpa.database}")
    private Database database;

    @Override
    public void doThirdPartyDbCollectData(String organizeCode, String cfgCode, String userInfo) {

        log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC ---", organizeCode, cfgCode);

        List<MesConfig> cfgList = getCfgList(organizeCode, cfgCode, userInfo);

        if (CollectionUtils.isEmpty(cfgList)) return;

        for (MesConfig cfg : cfgList) {

            if (null == cfg) continue;

            SxThirdPartyDbCollectDataModel collect = getCfgModel(organizeCode, cfg, userInfo);

            log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} START --- collect:{} ---", organizeCode, cfgCode, cfg.getCfgKey(), null == collect ? MesPcnExtConstWords.EMPTY : JSONObject.toJSONString(collect));

            if (null == collect) continue;

            try {

                ((ISxThirdPartyDbCollectDataStrategyService) SpringContextsUtil.getBean(collect.getStrategyClass())).exec(collect);

                log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} END --- execResult[{}] execSize[{}] ---", organizeCode, cfgCode, cfg.getCfgKey(), collect.getExecResult(), collect.getExecSize());

            } catch (Exception e) {

                saveCurExecResult(organizeCode, cfg, userInfo, String.format("Exception:%s", e.getMessage()));

            }

        }

    }

    private SxThirdPartyDbCollectDataModel getCfgModel(String organizeCode, MesConfig cfg, String userInfo) {
        SxThirdPartyDbCollectDataModel collect = JSONObject.parseObject(cfg.getCfgValue(), SxThirdPartyDbCollectDataModel.class);
        if (null == collect) {
            saveCurExecResult(organizeCode, cfg, userInfo, String.format("cfgValue:%s 无效配置", cfg.getCfgValue()));
            return null;
        }
        String error = collect.checkValid();
        if (!StringUtils.isEmpty(error)) {
            saveCurExecResult(organizeCode, cfg, userInfo, String.format("cfgValue:%s 未设置:%s", cfg.getCfgValue(), error));
            return null;
        }
        return collect.organizeCode(organizeCode).userInfo(userInfo).cfgCode(cfg.getCfgCode()).objectCode(cfg.getCfgKey()).cfgValue(cfg.getCfgValue()).paritySyncDatabase(database.name()).defaultValue();
    }

    private List<MesConfig> getCfgList(String organizeCode, String cfgCode, String userInfo) {
        List<MesConfig> cfgList = configService.findMesConfigByCfgCode(cfgCode, organizeCode);
        cfgList = CollectionUtils.isEmpty(cfgList) ? null :
                cfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCfgValue()) && !StringUtils.isEmpty(o.getCfgKey())))
                        .distinct().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesConfig::getCfgKey))), ArrayList::new)
                );
        if (CollectionUtils.isEmpty(cfgList)) {
            MesThirdPartyDbCollectDataRecord record = new MesThirdPartyDbCollectDataRecord(cfgCode);
            log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- 未配置有效的参数配置 ---", organizeCode, cfgCode);
            thirdPartyDbCollectDataRecordService.exec(organizeCode, userInfo, record);
        }
        return cfgList;
    }

    private void saveCurExecResult(String organizeCode, MesConfig cfg, String userInfo, String message) {
        MesThirdPartyDbCollectDataRecord record = new MesThirdPartyDbCollectDataRecord(cfg.getCfgCode(), cfg.getCfgKey(), cfg.getCfgValue());
        log.info(record.message(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s --- %s ---", organizeCode, cfg.getCfgCode(), cfg.getCfgKey(), message)));
        thirdPartyDbCollectDataRecordService.exec(organizeCode, userInfo, record);
    }

}
