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

import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 采集工位节拍调度单例模式
 */
@Slf4j
public class SxCellTaktDispatchSingleton {

    protected volatile static Boolean isInit = false;

    private static class SxCellTaktDispatchHolder { private final static SxCellTaktDispatchSingleton INSTANCE = new SxCellTaktDispatchSingleton(); }

    public static SxCellTaktDispatchSingleton getInstance() { return SxCellTaktDispatchHolder.INSTANCE; }

    private SxCellTaktDispatchSingleton() { isInit = true; }

    private volatile static Map<String, SxCellTaktMonitorHandler> cellTaktMonitorMap = new ConcurrentHashMap<>();

    public static Boolean getIsInit() { return isInit; }

    public static synchronized void execMonitor(String org, Map<String, String> cfgMap) {
        if (CollectionUtils.isEmpty(cfgMap)) execMonitorRemove(getCellTaktMonitorMapKeyList(org));
        else execMonitorCompareToCfg(org, cfgMap);
    }

    private static void execMonitorRemove(List<String> removeKeyList) {
        if (!CollectionUtils.isEmpty(removeKeyList)) removeKeyList.stream().forEach(SxCellTaktDispatchSingleton::execMonitorRemove);
    }

    private static void execMonitorCompareToCfg(String org, Map<String, String> cfgMap) {
        List<String> cellTaktMonitorMapKeyList = getCellTaktMonitorMapKeyList(org);
        List<String> removeKeyList = CollectionUtils.isEmpty(cellTaktMonitorMapKeyList) ? null : cellTaktMonitorMapKeyList.stream().filter(o -> (!StringUtils.isEmpty(o) && !cfgMap.containsKey(o))).collect(Collectors.toList());
        execMonitorRemove(removeKeyList);
        execMonitorCompute(org, cfgMap);
    }

    private static List<String> getCellTaktMonitorMapKeyList(String org) {
        List<String> cellTaktMonitorMapKeyList = CollectionUtils.isEmpty(cellTaktMonitorMap) ? null : new ArrayList<>(cellTaktMonitorMap.keySet());
        return CollectionUtils.isEmpty(cellTaktMonitorMapKeyList) ? null : cellTaktMonitorMapKeyList.stream().filter(o -> (!StringUtils.isEmpty(o) && o.split(MesPcnExtConstWords.COLON)[0].equals(org))).collect(Collectors.toList());
    }

    private static void execMonitorRemove(String key) {
        cellTaktMonitorMap.computeIfPresent(key, (k, v) -> {
            v.cancel();
            cellTaktMonitorMap.remove(key);
            return null;
        });
    }

    private static void execMonitorCompute(String org, Map<String, String> cfgMap) {
        for (String key : cfgMap.keySet()) {
            if (StringUtils.isEmpty(key)) continue;
            String[] plcCodeArr = cfgMap.get(key).split(MesPcnExtConstWords.COMMA);
            if (null == plcCodeArr || plcCodeArr.length != 2) continue;
            cellTaktMonitorMap.compute(key, (k, v) -> {
                if (null == v) v = new SxCellTaktMonitorHandler(org);
                return v.plcCodeArr(plcCodeArr);
            });
        }
    }

}
