package cn.axzo.workflow.core.common.context;

import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.function.Supplier;

/**
 * 事件处理器中通用的上下文
 *
 * @author wangli
 * @since 2024/4/9 21:00
 */
public abstract class CommonContext<T> implements OperationContext {
    private T context;
    private ProcessInstance processInstance;
    private Deployment deployment;
    private Process process;
    private BpmnTaskDelegateAssigner initiator;
    private BpmnProcessInstanceVO instanceVO;
    private BpmnProcessDefinitionVO definitionVO;
    private String processInstanceVersion;

    public ProcessInstance getProcessInstance(Supplier<ProcessInstance> supplier) {
        if (Objects.isNull(processInstance)) {
            processInstance = supplier.get();
        }
        return processInstance;
    }

    public Deployment getDeployment(Supplier<Deployment> supplier) {
        if (Objects.isNull(deployment)) {
            deployment = supplier.get();
        }
        return deployment;
    }

    public Process getProcess(Supplier<Process> supplier) {
        if (Objects.isNull(process)) {
            process = supplier.get();
        }
        return process;
    }

    public BpmnProcessInstanceVO getInstanceVO(Supplier<BpmnProcessInstanceVO> supplier) {
        if (Objects.isNull(instanceVO)) {
            instanceVO = supplier.get();
        }
        return instanceVO;
    }

    public BpmnProcessDefinitionVO getDefinitionVO(Supplier<BpmnProcessDefinitionVO> supplier) {
        if (Objects.isNull(definitionVO)) {
            definitionVO = supplier.get();
        }
        return definitionVO;
    }

    public BpmnTaskDelegateAssigner getInitiator(Supplier<BpmnTaskDelegateAssigner> supplier) {
        if (Objects.isNull(initiator)) {
            initiator = supplier.get();
        }
        return initiator;
    }

    public String getProcessInstanceVersion(Supplier<String> supplier) {
        if (!StringUtils.hasText(processInstanceVersion)) {
            processInstanceVersion = supplier.get();
        }
        return processInstanceVersion;
    }

    @Override
    public void setContext(OperationContext context) {
        this.context = (T) context;
    }

    @Override
    public T getContext() {
        return context;
    }
}
