package cn.stylefeng.workflow.instance.modular.task.strategy.agree;

import cn.stylefeng.workflow.api.NodeApi;
import cn.stylefeng.workflow.api.entity.design.Node;
import cn.stylefeng.workflow.api.entity.task.RuTask;
import cn.stylefeng.workflow.api.enums.NodeTypeEnum;
import cn.stylefeng.workflow.api.pojo.config.node.NodeData;
import cn.stylefeng.workflow.api.pojo.config.node.approver.ApproverConfig;
import cn.stylefeng.workflow.api.pojo.config.node.approver.ApproverStrategy;
import cn.stylefeng.workflow.instance.modular.task.strategy.agree.base.*;

import java.util.ArrayList;
import java.util.List;

public class NodePassStrategyContext {

    public static boolean getAgreeStrategy(RuTask currentProcessTask, NodeApi nodeApi, boolean purePredictFlag) {

        Long reNodeId = currentProcessTask.getReNodeId();
        Node nodeInfo = nodeApi.getNodeInfo(reNodeId);

        if (nodeInfo.getNodeType().equals(NodeTypeEnum.APPLICANT.getNodeType())) {
            return true;
        }

        NodeData nodeData = nodeInfo.getNodeData();
        if (nodeData == null) {
            return false;
        }
        ApproverConfig approverConfig = nodeData.getApproverConfig();
        if (approverConfig == null) {
            return false;
        }
        ApproverStrategy approverStrategy = approverConfig.getApproverStrategy();
        if (approverStrategy == null) {
            return false;
        }
        Integer approverNodeType = approverStrategy.getApproverNodeType();
        if (approverNodeType == null) {
            return false;
        }

        List<BaseAgreeStrategy> agreeStrategies = new ArrayList<>();
        agreeStrategies.add(new AgreeSingleStrategy());
        agreeStrategies.add(new AgreeOrStrategy(purePredictFlag));
        agreeStrategies.add(new AgreeAndStrategy(purePredictFlag));
        agreeStrategies.add(new AgreeOneByOneStrategy(purePredictFlag));
        agreeStrategies.add(new AgreeInternalLoopStrategy());

        for (BaseAgreeStrategy agreeStrategy : agreeStrategies) {
            if (agreeStrategy.getStrategyExecuteFlag(approverNodeType)) {
                return agreeStrategy.strategyAction(currentProcessTask, approverStrategy);
            }
        }

        return false;
    }

}
