package com.muyu.rule.common.load;


import com.muyu.rule.common.scan.JavaCodeScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;


/**
 * @Author：张承志
 * @Package：com.muyu.rule.server.load
 * @Project：cloud-etl-rule
 * @name：JavaBinaryClassLoader
 * @Date：2024/8/22 20:54
 * java字节码文件   加载器
 */

public class JavaBinaryClassLoader extends ClassLoader{

    private static JavaBinaryClassLoader loader =new JavaBinaryClassLoader();

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


    /**
     *
      * @param name     class 类的文件名
     * @param pack      类所在的包名eg:com.ecoogy.etl.engine.
     * @param location  类文件的路径,设定目录: 设定目录时,需要在最后带上"/"
     *                 自定义路径获取Class对象
     */



private static  Class<?> loadClassByNameAndLocation(String name,String pack,File location){

    try {
        //将class文件的数据读入到byte数组中 转成二进制文件
        byte[] datas  = loader.loadClassData(name,location);
        //pack= loader.convert(pack);
        //通过byte数组加载Class对象
     String cc  =   pack+name;

        Class<?> aClass = loader.defineClass(cc, datas, 0, datas.length);
        log.info("成功加载规则引擎-> {} ",aClass.getName());
return aClass;
    } catch (IOException e) {
        log.error("从文件中加载类失败 {}", name, location, e);
        return null;
    }

}
    /**
     *
     * @param pack 类所在的包名 eg:com.szelink.test. 后面需要带个"."
     * @param location 包所在的路径
     * @return
     */
    public static Map<String ,Class<?>> loadClassesByLocation(String pack,String location){
int count =0;
        File[] childFiles = JavaCodeScan.javaBinaryByPath(location);
        HashMap<String, Class<?>> map = new HashMap<>();
        for (File f : childFiles) {
            String name = f.getName().substring(0, f.getName().indexOf(".class"));

          Class<?> c =  loadClassByNameAndLocation(name,pack,new File(location));
            System.out.println(++count);
        map.put(name,c);
        }
return map;
    }

    /**
     * 修改文件的格式
     * @param pack
     * @return
     */
    private String convert(String pack) {
        return pack;
    }

    public byte[] loadClassData(String name, File location)throws IOException {
        File classFile = new File(location, name + ".class");
        if (!classFile.exists()) {
            throw new FileNotFoundException("找不到类文件: " + classFile.getAbsolutePath());
        }
        return Files.readAllBytes(classFile.toPath());
    }
}
