package cn.fateverse.query.handler.engine.impl;

import cn.fateverse.common.code.engine.JavaCodeEngine;
import cn.fateverse.common.code.model.EngineResult;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.enums.DataAdapterType;
import cn.fateverse.query.handler.engine.EngineExecuteHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

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

/**
 * Java代码执行器
 *
 * @author Clay
 * @date 2023-10-29  19:34
 */
@Slf4j
@Component
public class JavaEngineExecuteHandler implements EngineExecuteHandler {

    private final JavaCodeEngine javaCodeEngine;


    public JavaEngineExecuteHandler(JavaCodeEngine javaCodeEngine) {
        this.javaCodeEngine = javaCodeEngine;
    }


    @Override
    public EngineResult execute(DataAdapter dataAdapter, Object data, boolean development) {
        if (!DataAdapterType.JAVA.equals(dataAdapter.getType())) {
            return null;
        }
        return javaCodeEngine.execute(dataAdapter.getExecuteCode(), getClassName(dataAdapter),
                "execute", new Class[]{List.class}, new Object[]{data}, development);
    }

    private static String getClassName(DataAdapter dataAdapter) {
        return "DataAdapter" + dataAdapter.getAdapterId();
    }


    @Override
    public Boolean preconditioning(DataAdapter dataAdapter) {
        if (dataAdapter.getType() != DataAdapterType.JAVA) {
            return Boolean.FALSE;
        }
        String modifiedCode = modifiedCode(dataAdapter.getCode());
        String replacedCode = replacedClass(modifiedCode, getClassName(dataAdapter));
        String IMPORT_CODE = "import java.util.*;\n" +
                "import java.util.stream.*;\n";
        dataAdapter.setExecuteCode(IMPORT_CODE + replacedCode);
        return Boolean.TRUE;
    }


    @Override
    public Boolean remove(DataAdapter dataAdapter) {
        if (dataAdapter.getType() != DataAdapterType.JAVA) {
            return Boolean.FALSE;
        }
        return javaCodeEngine.remove(getClassName(dataAdapter));
    }

    /**
     * 替换类定义
     *
     * @param code      待替换的代码
     * @param className 替换后的类名
     * @return 替换后的代码
     * @throws CustomException 如果类定义未被匹配到则抛出异常
     */
    private String replacedClass(String code, String className) {
        // 正则表达式匹配类定义
        String regex = "public class .*? ";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(code);
        if (matcher.find()) {
            // 执行替换操作
            return code.replaceFirst(regex, "public class " + className + " ");
        } else {
            throw new CustomException("请勿修改类定义");
        }
    }

    /**
     * 去除import引入的内容
     *
     * @param code 需要去除的代码
     * @return 处理完成的代码
     */
    private String modifiedCode(String code) {
        // 定义正则表达式，用于匹配代码中的指定内容
        String regex = "public class DataAdapter \\{";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);
        // 使用编译后的正则表达式对代码进行匹配
        Matcher matcher = pattern.matcher(code);
        // 如果匹配成功，则执行删除操作
        if (matcher.find()) {
            // 使用replaceFirst方法替换匹配到的内容为空字符串，实现删除操作
            int classIndex = matcher.start();
            return code.substring(classIndex);
        } else {
            // 如果匹配失败，则抛出自定义异常
            throw new CustomException("代码格式异常,请检查");
        }
    }
}
