package cn.axzo.workflow.core.service.support;

import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.azxo.framework.common.utils.StringUtils;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;

import java.io.Serializable;

import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EXECUTION_LOST_ID_ERROR;


/**
 * 流程定义内部的表达式评估命令器
 *
 * @author wangli
 * @since 2023/10/9 19:30
 */
public class ExpressionConditionCmd implements Command<Boolean>, Serializable {
    protected final RuntimeService runtimeService;
    protected final ProcessEngineConfigurationImpl processEngineConfiguration;
    protected final String processInstanceId;
    protected final String exp;

    public ExpressionConditionCmd(RuntimeService runtimeService,
                                  ProcessEngineConfigurationImpl processEngineConfiguration,
                                  String processInstanceId, String exp) {
        this.runtimeService = runtimeService;
        this.processEngineConfiguration = processEngineConfiguration;
        this.processInstanceId = processInstanceId;
        this.exp = exp;
    }

    @Override
    public Boolean execute(CommandContext commandContext) {
        Expression expression = processEngineConfiguration.getExpressionManager().createExpression(this.exp);
        ExecutionEntity executionEntity;
        if (StringUtils.isNotBlank(this.processInstanceId)) {
            executionEntity = (ExecutionEntity) runtimeService.createProcessInstanceQuery()
                    .processInstanceId(this.processInstanceId).includeProcessVariables().singleResult();
        } else {
            // 不能单纯的 new ExecutionEntityImpl, 后续在调用 setVariables 时,
            // 引擎用了很多 ExecutionEntityImpl 的其他属性,这些属性都是在 new 不会自动生成的
            throw new WorkflowEngineException(ENGINE_EXECUTION_LOST_ID_ERROR);
        }
        Object value = expression.getValue(executionEntity);
        return value != null && "true".equals(value.toString());
    }

}
