package org.dromara.wflow.workflow.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.dromara.wflow.workflow.bean.process.ProcessNode;
import org.dromara.wflow.bean.entity.WflowSubProcess;
import org.dromara.wflow.mapper.WflowSubProcessMapper;
import org.dromara.wflow.utils.BeanUtil;
import org.dromara.wflow.workflow.bean.dto.ProcessInstanceOwnerDto;
import org.dromara.wflow.workflow.bean.process.ProcessStatus;
import org.dromara.wflow.workflow.config.WflowGlobalVarDef;
import org.dromara.wflow.workflow.config.callActivity.WflowCallActivityBehavior;
import org.dromara.wflow.workflow.service.ProcessNodeCatchService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;

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

/**
 * @author : willian fu
 * @date : 2023/12/12
 * 子流程初始化任务，用来初始化子流程变量等信息，会在子流程启动后调用
 */
@Slf4j
public class SubProcessInitTask implements JavaDelegate {

    public static WflowSubProcessMapper processMapper;
    public static ProcessNodeCatchService nodeCatchService;

    public static RuntimeService runtimeService;

    public SubProcessInitTask() {
        runtimeService = BeanUtil.getBean(RuntimeService.class);
        processMapper = BeanUtil.getBean(WflowSubProcessMapper.class);
        nodeCatchService = BeanUtil.getBean(ProcessNodeCatchService.class);
    }

    @Override
    public void execute(DelegateExecution execution) {
        WflowSubProcess subProcess = processMapper.selectOne(new LambdaQueryWrapper<WflowSubProcess>()
                .select(WflowSubProcess::getProcess)
                .eq(WflowSubProcess::getProcDefId, execution.getProcessDefinitionId()));
        Map<String, ProcessNode<?>> nodeMap = nodeCatchService.reloadProcessByStr(subProcess.getProcess());
        Map<String, Object> propsMap = nodeMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
                v -> null == v.getValue().getProps() ? new HashMap<>() : v.getValue().getProps()));
        ProcessInstanceOwnerDto ownerDto = WflowCallActivityBehavior.OWNER.get();
        execution.setVariable(WflowGlobalVarDef.INITIATOR, ownerDto.getOwner());
        execution.setVariable(WflowGlobalVarDef.START_DEPT, ownerDto.getOwnerDeptId());
        //设置节点流程变量缓存
        execution.setVariable(WflowGlobalVarDef.WFLOW_NODE_PROPS, propsMap);
        runtimeService.updateBusinessStatus(execution.getProcessInstanceId(), ProcessStatus.RUNNING.toString());
        log.info("设置子流程{}流程变量[{}, {}]", execution.getProcessInstanceId(), ownerDto.getOwner(), ownerDto.getOwnerDeptId());
    }
}
