package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.rulematch;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesEquipVariableCfgRuleMatchDispatchService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCfgCollectContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCollectContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 取一组全部匹配的结果
 */
@Slf4j
@Service
public class MesEvcRuleMatchCompareValueService implements IMesEquipVariableCfgRuleMatchDispatchService {

    @Override
    public Boolean matchEquipVariableCfgCollectContext(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext, String variableCategory, List<MesEquipVariableCfgCollectContext> collectContextList) {

        Map<String, List<MesEquipVariableCfgCollectContext>> ruleCategoryMap = CollectionUtils.isEmpty(collectContextList) ? null : collectContextList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesEquipVariableCfgCollectContext::getRuleCategory));

        if (CollectionUtils.isEmpty(ruleCategoryMap)) return false;

        for(Map.Entry<String, List<MesEquipVariableCfgCollectContext>> entry : ruleCategoryMap.entrySet()) {

            if (null == entry) continue;

            //任意一组规则全部匹配
            if (matchEquipVariableCfgCollectContext(entry.getKey(), entry.getValue())) return true;

        }

        return false;

    }

    private Boolean matchEquipVariableCfgCollectContext(String ruleCategory, List<MesEquipVariableCfgCollectContext> collectContextList) {

        for (MesEquipVariableCfgCollectContext collectContext : collectContextList) {

            if (null == collectContext) continue;

            //任意一个规则不匹配
            if (!matchEquipVariableCfgCollectContext(collectContext)) return false;

        }

        return true;
    }

    private Boolean matchEquipVariableCfgCollectContext(MesEquipVariableCfgCollectContext collectContext) {

        if (StringUtils.isEmpty(collectContext.getValue()) || CollectionUtils.isEmpty(collectContext.getEquipVariableCollectContextList())) return false;

        //一个规则如果对应多个数据变量,则默认必须全部匹配
        for (MesEquipVariableCollectContext equipVariableCollectContext : collectContext.getEquipVariableCollectContextList()) {

            if (null == equipVariableCollectContext) continue;

            if (StringUtils.isEmpty(equipVariableCollectContext.getEquipVariableValue()))  return false;

            //比对值是否相等
            if (!compareTo(collectContext.getValue(), equipVariableCollectContext.getEquipVariableValue(), equipVariableCollectContext.getDataType())) return false;

        }

        return true;
    }

    private Boolean compareTo(String value1, String value2, Integer dataType) {
        value1 = value1.toUpperCase();
        value2 = value2.toUpperCase();
        if (value1.equals(value2)) return true;
        if (StringUtils.isEmpty(dataType) || dataType.compareTo(MesExtEnumUtil.VARIABLE_DATA_TYPE.VARIABLE_DATA_TYPE_40.getValue()) != 0) return false;
        value1 = transferValueBoo(value1);
        return value1.equals(value2);
    }

    private String transferValueBoo(String value) {
        if (value.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) return CommonEnumUtil.TRUE_OR_FALSE.TRUE.name();
        if (value.equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr())) return CommonEnumUtil.TRUE_OR_FALSE.FALSE.name();
        if (value.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.name())) return CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
        if (value.equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.name())) return CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr();
        return value;
    }

}
