package com.brilliance.isc.common.validator.es.factory;

import com.brilliance.isc.common.validator.es.support.IEsLoader;
import com.brilliance.isc.common.validator.es.utils.EsConstant;
import com.brilliance.isc.common.validator.es.utils.EsSpringUtils;
import com.brilliance.isc.common.validator.es.vo.EnvDespVo;
import lombok.Getter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * JS 加载读取工厂
 * @author fukai
 */
@Configuration("es-factory")
@Getter
public class ScriptTemplateFactory {

    @Value("${es.validator.path:es-script}")
    private String path;

    @Value("${es.validator.loader:esClassLoader}")
    private String loader;

    @Value("${es.validator.mode:release}")
    private String mode;



    public String getEsScript(EnvDespVo envDespVo, Set<String> loadSet) {
        //根据loader名称获取
        String curLoader = envDespVo.getLoader();
        if(curLoader == null || curLoader.isEmpty()){
            curLoader = loader;
        }
        IEsLoader esLoader = EsSpringUtils.getBean(curLoader);
        String curScript =  esLoader.loadEsScript(envDespVo);
        //处理load
        if(EsConstant.VUE_TERMINAL.equals(envDespVo.getTerminal())){
            curScript = dealLoadForVue(curScript,envDespVo,loadSet);
        }
        if(EsConstant.JAVA_TERMINAL.equals(envDespVo.getTerminal())){
            //Java端执行，不需要async、await
            curScript = curScript.replaceAll("async|await","");
        }
        /**
         * 替换常量
         */
        curScript = curScript.replaceAll("CUR_PATH", '"'+this.getCurPath()+'"');
        return curScript;
    }

    public boolean isDebugMode(){
        return "debug".equalsIgnoreCase(mode);
    }

    public String saveBakEsScript(EnvDespVo envDespVo,String source){
        IEsLoader esLoader = EsSpringUtils.getBean(loader);
        return esLoader.saveBakScript(envDespVo,source);
    }

    public String getCurPath() {
        //根据loader名称获取
        IEsLoader esLoader = EsSpringUtils.getBean(loader);
        return esLoader.getCurPath(this.getPath());
    }

    /**
     * 模块之间的以来千万不要出现循环引用
     * @return
     */
    public String dealLoadForVue(String curScript,EnvDespVo envDespVo,Set<String> loadSet){
        //load(CUR_PATH+""
        String reg = "load\\s*\\(CUR_PATH\\s*\\+\\s*('|\")([\\w/]+)\\.js('|\")\\s*\\)\\s*;?";
        StringBuilder sb = new StringBuilder(curScript);
        Matcher matcher = Pattern.compile(reg).matcher(curScript);
        EnvDespVo envDespVoBak = EnvDespVo.builder().build();
        BeanUtils.copyProperties(envDespVo,envDespVoBak);
        int offset = 0;
        while(matcher.find()){
            String module = matcher.group(2);
            if(loadSet != null) {
                loadSet.add(module);
            }
            if(EsConstant.JS_ES6_MODULE.equals(envDespVoBak.getSubtype())) {
                //把load删除掉
                sb.delete(matcher.start()+offset,matcher.end()+offset);
                offset -= matcher.group().length();
            }else if(EsConstant.JS_TYPE.equals(envDespVoBak.getSubtype())){
                envDespVoBak.setScriptName(module);
                String moduleScript = "\n" + this.getEsScript(envDespVoBak, loadSet) + "\n";
                sb.replace(matcher.start() + offset, matcher.end() + offset, moduleScript);
                offset = offset + (moduleScript.length() - matcher.group().length());
            }
        }
        return sb.toString();
    }
}
