package cd.casic.ci.process.engine.worker.base;


import cd.casic.ci.process.constant.CommandConstant;
import cd.casic.ci.process.engine.constant.PipelineBehaviorConstant;
import cd.casic.ci.process.engine.enums.ContextStateEnum;
import cd.casic.ci.process.engine.manager.LoggerManager;
import cd.casic.ci.process.engine.manager.PostHandlerManager;
import cd.casic.ci.process.engine.manager.RunContextManager;
import cd.casic.ci.process.engine.runContext.BaseRunContext;

import cd.casic.ci.process.engine.runContext.TaskRunContext;
import cd.casic.ci.process.process.dataObject.base.PipBaseElement;
import cd.casic.ci.process.process.dataObject.task.PipTask;

import cd.casic.ci.process.process.service.resource.ResourceManagerService;
import cd.casic.framework.commons.exception.ServiceException;
import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants;
import jakarta.annotation.Resource;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.swing.text.StringContent;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Data
@Slf4j
public abstract class BaseWorker implements Runnable{
    // 一些属性
    @Resource
    protected RunContextManager contextManager;
    protected String contextKey;
    @Resource
    protected LoggerManager loggerManager;
    @Resource
    protected ResourceManagerService resourceManagerService;
    @Resource
    protected PostHandlerManager postHandlerManager;

    @Override
    public void run() {
        if (StringUtils.isEmpty(contextKey)) {
            log.error("请设置当前worker的contextKey");
            return;
        }
        doWorker(contextKey);
    }
    public void doWorker(String contextKey){
        BaseRunContext context = contextManager.getContext(contextKey);
        if (context instanceof TaskRunContext taskRunContext){
            try {
                Map<String, Object> globalVariables = context.getGlobalVariables();
                Object fromError = globalVariables.get(PipelineBehaviorConstant.PIPELINE_EXECUTE_FROM_ERROR);
                if (Boolean.TRUE.equals(fromError)&&ContextStateEnum.HAPPY_ENDING.getCode().equals(taskRunContext.getState().get())) {
                    append(taskRunContext,"跳过执行"+CommandConstant.ENTER);
                } else{
                    if (this instanceof PassableWorker passableWorker) {
                        taskRunContext.changeContextState(ContextStateEnum.SUSPEND);
                        passableWorker.waitForPermission();
                    } else {
                        taskRunContext.changeContextState(ContextStateEnum.READY);
                        taskRunContext.changeContextState(ContextStateEnum.RUNNING);
                    }
                    execute(taskRunContext);
                }
            } catch (Exception e) {
                log.error("================worker执行报错：",e);
                // todo 根据配置决定失败是跳过还是直接失败，如果直接跳过，状态改为跳过，如果直接失败状态就改为失败
                PipBaseElement contextDef = taskRunContext.getContextDef();
                if (contextDef instanceof PipTask task) {
                    Map<String, Object> taskProperties = task.getTaskProperties();
                    Object taskSkip = taskProperties.get(PipelineBehaviorConstant.TASK_SKIP_KEY);
                    if (Integer.valueOf("1").equals(taskSkip)) {
                        taskRunContext.changeContextState(ContextStateEnum.SKIP_TO);
                        append(context,e.getMessage());
                    } else{
                        taskRunContext.changeContextState(ContextStateEnum.BAD_ENDING);
                        append(context,e.getMessage());
                    }
                }

                return;
            }
            // TODO 执行结束修改context的state,并且通知父类
            taskRunContext.changeContextState(ContextStateEnum.HAPPY_ENDING);
        }
    }
    public void append(BaseRunContext context, String content){
        if (context instanceof TaskRunContext taskRunContext) {
            content = content+ CommandConstant.ENTER;
            loggerManager.append(taskRunContext.getContextDef().getId(),content);
        }
    }
    public abstract void execute(TaskRunContext context);
    protected void toBadEnding(){
        throw new ServiceException(GlobalErrorCodeConstants.PIPELINE_ERROR.getCode(),"");
    }
    /**
     *  往全局变量中保存变量，作用域为全局
     * */
    protected void putGlobalVariable(TaskRunContext context,String key,Object value){
        Map<String, Object> globalVariables = context.getGlobalVariables();
        globalVariables.put(key,value);
    }
    /**
     *  往当前执行链路中保存变量，作用域为当前二级stage
     * */
    protected void putSecondStageVariable(TaskRunContext context,String key,Object value){
        BaseRunContext stageContext = context.getParentContext();
        Map<String, Object> localVariables = stageContext.getLocalVariables();
        localVariables.put(key,value);
    }
    protected Object getGlobalVariable(TaskRunContext context,String key){
        Map<String, Object> globalVariables = context.getGlobalVariables();
        return globalVariables.get(key);
    }
    protected Object getSecondStageVariable(TaskRunContext context,String key){
        BaseRunContext stageContext = context.getParentContext();
        Map<String, Object> localVariables = stageContext.getLocalVariables();
        return localVariables.get(key);
    }
    /**
     *  就近获取从secondStage 到pipeline 逐级获取获取到了直接返回
     * */
    protected Object getVariableNearby(TaskRunContext context,String key){
        BaseRunContext parentContext = context.getParentContext();
        Map<String, Object> localVariables = parentContext.getLocalVariables();
        Map<String, Object> globalVariables = context.getGlobalVariables();
        if (localVariables.containsKey(key)) {
            return localVariables.get(key);
        }
        if (globalVariables.containsKey(key)) {
            return globalVariables.get(key);
        }
        return null;
    }
}
