package com.seamew.lottery.domain.rule.service.engine;

import com.seamew.lottery.common.Constants;
import com.seamew.lottery.domain.rule.model.aggregates.TreeRuleRich;
import com.seamew.lottery.domain.rule.model.req.DecisionMatterReq;
import com.seamew.lottery.domain.rule.model.res.EngineResult;
import com.seamew.lottery.domain.rule.model.vo.TreeNodeVO;
import com.seamew.lottery.domain.rule.model.vo.TreeRootVO;
import com.seamew.lottery.domain.rule.service.engine.EngineConfig;
import com.seamew.lottery.domain.rule.service.engine.EngineFilter;
import com.seamew.lottery.domain.rule.service.logic.LogicFilter;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * @Author: seamew
 * @Title: EngineBase
 * @CreateTime: 2023年02月25日 17:08:00
 * @Description: 规则引擎基础类
 * @Version: 1.0
 */
@Slf4j
public abstract class EngineBase extends EngineConfig implements EngineFilter {
    @Override
    public EngineResult process(DecisionMatterReq matter) {
        throw new RuntimeException("未实现规则引擎服务");
    }

    protected TreeNodeVO engineDecisionMaker(TreeRuleRich treeRuleRich, DecisionMatterReq matter) {
        TreeRootVO treeRoot = treeRuleRich.getTreeRoot();
        Map<Long, TreeNodeVO> treeNodeMap = treeRuleRich.getTreeNodeMap();

        // 规则树根ID
        Long rootNodeId = treeRoot.getTreeRootNodeId();
        TreeNodeVO treeNodeInfo = treeNodeMap.get(rootNodeId);

        // 节点类型[NodeType]；1子叶、2果实
        while (Constants.NodeType.STEM.equals(treeNodeInfo.getNodeType())) {
            String ruleKey = treeNodeInfo.getRuleKey();
            LogicFilter logicFilter = logicFilterMap.get(ruleKey);
            String matterValue = logicFilter.matterValue(matter);
            Long nextNode = logicFilter.filter(matterValue, treeNodeInfo.getTreeNodeLineInfoList());
            treeNodeInfo = treeNodeMap.get(nextNode);
            log.info("决策树引擎=>{} userId：{} treeId：{} treeNode：{} ruleKey：{} matterValue：{}", treeRoot.getTreeName(), matter.getUserId(), matter.getTreeId(), treeNodeInfo.getTreeNodeId(), ruleKey, matterValue);
        }

        return treeNodeInfo;
    }
}
