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

import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;

/**
 * 采集工位节拍监控处理器
 */
public class SxCellTaktMonitorHandler {

    protected volatile Boolean isOpen = true;

    protected volatile Boolean isRetry = false;

    protected volatile Integer version = 0;

    private SxThirdPartyPlcCollectStepFilterChain filterChain;

    private ExecutorService executorService;

    private ListenableFuture<Object> listenFuture;

    private volatile String plcCode2Flag;

    private volatile String plcCode2Data;

    private String org;

    private String key;

    private StepResult stepResult;

    public SxCellTaktMonitorHandler(String org, String key) {
        this.org = org;
        this.key = key;
        initStepResult();
        executorService = SpringContextsUtil.getBean(ExecutorService.class);
        ListeningExecutorService listenExecutor = MoreExecutors.listeningDecorator(executorService);
        listenFuture = listenExecutor.submit(() -> {
            execMonitor();
            return null;
        });
    }

    private void initStepResult() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put(MesPcnExtConstWords.ORGANIZE_CODE, org);
        dataMap.put(MesPcnExtConstWords.KEY, key);
        dataMap.put(MesPcnExtConstWords.BUSI_CODE, MesPcnExtConstWords.COLLECT_CELL_TAKT);
        dataMap.put(MesPcnExtConstWords.WORK_CENTER_CODE, key.split(MesPcnExtConstWords.COLON)[2]);
        dataMap.put(MesPcnExtConstWords.WORK_CELL_CODE, key.split(MesPcnExtConstWords.COLON)[3]);
        stepResult = StepResult.getSuccessComplete().data(dataMap);
    }

    public SxCellTaktMonitorHandler isRetry(String[] plcCodeArr) {
        version ++;
        if (isRetry) return this;
        if (StringUtils.isEmpty(plcCode2Flag) || !plcCode2Flag.equals(plcCodeArr[0])) plcCode2Flag = null;
        if (StringUtils.isEmpty(plcCode2Data) || !plcCode2Data.equals(plcCodeArr[1])) plcCode2Data = null;
        if (!StringUtils.isEmpty(plcCode2Flag) && !StringUtils.isEmpty(plcCode2Data)) return this;
        isRetry = true;
        this.plcCode2Flag = plcCodeArr[0];
        this.plcCode2Data = plcCodeArr[1];
        return this;
    }

    public void cancel() {
        isOpen = false;
        if (null != listenFuture) listenFuture.cancel(true);
    }

    public Boolean version() { return version == 1 ? true : false; }

    private void instanceFilterChain() {

        filterChain = new SxThirdPartyPlcCollectStepFilterChain(org, key, MesPcnExtConstWords.COLLECT_CELL_TAKT, plcCode2Flag, plcCode2Data);

        filterChain.add(new SxThirdPartyPlcCollectReadPlcStepService(plcCode2Flag).targetValue(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr()))
                .add(new SxThirdPartyPlcCollectReadPlcStepService(plcCode2Data))
                .add(new SxThirdPartyPlcCollectWritePlcStepService(plcCode2Flag).targetValue(MesPcnExtConstWords.ZERO_STR))
                .add(new SxThirdPartyPlcCollectCellTaktStepService().targetField(plcCode2Data));

        isRetry = false;

    }

    private void execMonitor() {

        while (isOpen) {

            if (StringUtils.isEmpty(plcCode2Flag) || StringUtils.isEmpty(plcCode2Data)) continue;

            if (isRetry || null == filterChain) instanceFilterChain();

            filterChain.exec(stepResult);

        }
    }


}
