package com.ruoyi.execution.produce;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.execution.produce.dispersed.service.IRunBPMService;
import com.ruoyi.execution.produce.dispersed.service.IScriptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 调用脚本逻辑执行类
 * * 执行所有脚本类
 * * 将IScriptService的实现类的Spring Bean的作用域设置为prototype，
 * * 这样每次调用applicationContext.getBean()时都会返回一个新的实例。
 * * 这样可以避免多线程环境下共享实例的问题
 *
 * @author hanzihang
 * @date 2023/11/13
 */
@Component
public class RunImplementationClass<J> {

    @Autowired
    private ApplicationContext applicationContext;


    private static final Logger log = LoggerFactory.getLogger(RunImplementationClass.class);

    /**
     * @param implementationName 实现类名称
     * @return
     */
    public AjaxResult RunBPMImplementationClassLogicCode(String implementationName, String executionFlowKey, String executionNodeKey, Map<String, Object> executionMap) {
        AjaxResult ajaxResult = new AjaxResult();
        if (applicationContext.containsBean(implementationName)) {
            IRunBPMService iRunBPMService = (IRunBPMService) applicationContext.getBean(implementationName, IRunBPMService.class);
            // 校验当前需要执行的脚本是否存在
            if (iRunBPMService.isVerificationMethod()) {
                // 脚本执行前验证
                if (iRunBPMService.preValidation(executionFlowKey, executionNodeKey, executionMap).get("code").equals("200")) {
                    ajaxResult = iRunBPMService.executeNode(executionFlowKey, executionNodeKey, executionMap);
                    iRunBPMService.afterValidation(executionFlowKey, executionNodeKey, executionMap);
                }
                // 执行清理操作
                iRunBPMService.preDestroy();
            }
            log.info("Service execution successful：" + implementationName);
            return ajaxResult;
        } else {
            log.error("Service not found for name: " + implementationName);
            return AjaxResult.error("网络出现问题！请联系管理员！！！");
        }
    }

    /**
     * @param implementationName 实现类名称
     * @return
     */
    public boolean RunScriptImplementationClassLogicCode(String implementationName, J parameter) {
        if (applicationContext.containsBean(implementationName)) {
            IScriptService iScriptService = (IScriptService) applicationContext.getBean(implementationName, IScriptService.class);
            // 校验当前需要执行的脚本是否存在
            if (iScriptService.isVerificationMethod()) {
                // 脚本执行前验证
                if ((Boolean) iScriptService.preExecutionScript(parameter)) {
                    iScriptService.ExecutionScript(parameter);
                    iScriptService.afterExecutionScript(parameter);
                }
                // 执行清理操作
                return iScriptService.preDestroy();
            }
            log.info("Service execution successful：" + implementationName);
            return true;
        } else {
            log.error("Service not found for name: " + implementationName);
            return false;
        }
    }

    /**
     * 根据脚本名称校验脚本是否存在
     *
     * @param implementationName 脚本名称
     * @return
     */
    public boolean isVerificationMethod(String implementationName) {
        if (applicationContext.containsBean(implementationName)) {
            IScriptService iScriptService = (IScriptService) applicationContext.getBean(implementationName, IScriptService.class);
            // 校验当前需要执行的脚本是否存在
            return iScriptService.isVerificationMethod();
        } else {
            return false;
        }
    }
}
