package com.muyu.rule.server.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.common.core.enums.SystemYesNo;
import com.muyu.etl.domain.DataValue;
import com.muyu.rule.common.basic.BasicEngine;
import com.muyu.rule.common.domain.DataValueFie;
import com.muyu.rule.common.domain.DataValueRow;
import com.muyu.rule.common.domain.DataValueRows;
import com.muyu.rule.common.domain.RuleEngineVersion;
import com.muyu.rule.common.load.ExternalClassLoader;
import com.muyu.rule.common.utils.OssUtil;
import com.muyu.rule.server.mapper.RuleEngineVersionMapper;
import com.muyu.rule.server.service.RuleEngineVersionService;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

import static com.muyu.rule.common.constant.SuffixClass.Suffix_CLASS;
import static com.muyu.rule.common.constant.SuffixClass.Suffix_JAVA;
import static com.muyu.rule.common.utils.LoadEngineClass.*;


/**
 * @Author：张承志
 * @Package：com.muyu.rule.server.service.impl
 * @Project：cloud-etl-rule
 * @name：RuleEngineServiceImpl
 * @Date：2024/8/25 14:17
 */
@Log4j2
@Service
public class RuleEngineVersionServiceImpl extends ServiceImpl<RuleEngineVersionMapper, RuleEngineVersion> implements RuleEngineVersionService {

    @Override
    public List<RuleEngineVersion> selectRuleEngineVersion(Long id) {

        LambdaQueryWrapper<RuleEngineVersion> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(
                RuleEngineVersion::getRuleId, id);

        List<RuleEngineVersion> versionList = this.list(queryWrapper);

        return versionList;
    }

    @Override
    public void activate(Long id) {
        this.updateOpen(id, SystemYesNo.YES.getCode());
    }

    @Override
    public void disable(Long id) {
        this.updateOpen(id, SystemYesNo.NO.getCode());
    }


    /**
     * bucket名称
     *
     * @return
     */
    private static String bucketName = "zcz-vfd-1000";

    /**
     * 上传
     *
     * @param versionClazz java源代码
     * @param className    类的名
     */
    @Override
    public void Upload(String versionClazz, String className) {

        /**
         * 将java源码存入OSS
         */
        OssUtil.deliteOssClient(className + Suffix_CLASS);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(versionClazz.getBytes());
        OssUtil.uploadFileInputStreamForBucket(bucketName, className + Suffix_CLASS, byteArrayInputStream);

    }

    @Override
    public Object readByOss(String className) {

        String string = OssUtil.readFileContentFromOSS(bucketName, className);

        return string;
    }

    /**
     * 存放实例化引擎的容器
     */

    /**
     * 服务器的存放java源代码的位置
     */
    public static final String engineWorkSourcePath = "/home/source/";


    /**
     * 引擎加载需要引入类和包文件的位置
     */
    public static final String importClassAndPackPath = "home/lib/";

    /**
     * 规则引擎的包的路径
     */
    public static final String className_prefix = "com.muyu.rule.common.engine.";

    /**
     * 服务器存放引擎的class文件的位置
     *
     * @param className 类名
     * @param versionClazz 源代码
     */

    public static final String serverClassPath = "com/muyu/rule/common/engine/";


    /**
     * 编译
     * @param className 类名
     * @param versionClazz 源代码
     */
    @Override
    public void complierClass(String className, String versionClazz) {
        log.info("======>" + versionClazz);
        String ossFilePath = className + Suffix_JAVA;
        //创建服务器项目容器的java源码文件目录路径
        File serverFile = new File(engineWorkSourcePath, ossFilePath);
        //如果目录不存在,则创建目录
        if (!serverFile.getParentFile().exists()) {
            serverFile.getParentFile().mkdirs();
        }
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(serverFile))) {
            writer.write(versionClazz);
            System.out.println("文件已成功创建并写入Java源码。");
        } catch (IOException e) {
            System.err.println("发生错误：" + e.getMessage());
        }

        JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
        //
        InputStream first = null; // 程序的输入  null 用 system.in
        OutputStream second = null; // 程序的输出 null 用 system.out
        OutputStream third = null;  // 程序的错误输出 .,null 用 system.err
        // 程序编译参数 注意 编译目录是项目的目录
        String[] strings = {"-classpath", "home/lib/", "-verbose", "-d", "home/lib/", "home/source/" + className + ".java"};
        log.info("规则引擎的编译参数{}[]", Arrays.toString(strings));
        // 0 表示成功， 其他表示出现了错误
        System.out.println(Arrays.toString(strings));
        int i = javaCompiler.run(first, second, third, strings);
        if (i == 0) {
            System.out.println("成功");
        } else {
            System.out.println("错误");
        }

        OssUtil.ssss(className);
    }

    /**
     * 加载规则引擎
     *
     * @param className 规则引擎类名
     */


    /**
     * 修改激活
     * @param id
     * @param open
     */
    public void updateOpen(Long id, String open) {

        UpdateWrapper<RuleEngineVersion> updateWrapper = new UpdateWrapper<>();

        updateWrapper.eq("id", id).set("open", open);

        this.update(updateWrapper);
    }

    /**
     * 实现测试数据
     *
     * @param className 类名
     * @param dataValue ktvl数据
     * @return
     */
    @Override
    public DataValue testEngine(String className, DataValueFie dataValue) {
        log.info("测试的数据[]{}:" + dataValue);
        log.info("测试的className[]{}:" + className);

        BasicEngine<DataValueFie> valueBasicEngine = engineMap.get(className);
        log.info(valueBasicEngine.toString());
        valueBasicEngine.set(dataValue);
        valueBasicEngine.execution();
        DataValueFie value = valueBasicEngine.get();
        log.info(value+"-----------");
        return value.getDataValue();
    }

    @Override
    public DataValue[] testEngine(String className, DataValueRow dataValue) {
        log.info("测试的数据[]{}:" + dataValue);
        log.info("测试的className[]{}:" + className);
        BasicEngine<DataValueRow> basicEngine = engineRowMap.get(className);
        log.info(basicEngine.toString());
        basicEngine.set(dataValue);

        basicEngine.execution();
        DataValueRow dataValues = basicEngine.get();
        return dataValues.getDataValue();
    }


    @Override
    public DataValue[][] testEngine(String className, DataValueRows dataValues) {
        log.info("测试的className[]{}:" + className);
        BasicEngine<DataValueRows> basicEngine = engineDataSetMap.get(className);
        log.info(basicEngine.toString());
        basicEngine.set(dataValues);

        basicEngine.execution();

        DataValueRows dataValues1 = basicEngine.get();

        return dataValues1.getDataValue();
    }

    public void execution(String engineKey,DataValueFie dataValue){

        BasicEngine<DataValueFie> dataValueBasicEngine = engineMap.get(engineKey);
        dataValueBasicEngine.set(dataValue);
        dataValueBasicEngine.execution();
    }


    public void execution(String engineKey,DataValueRow dataValue){

        BasicEngine<DataValueRow> dataValueBasicEngine = engineRowMap.get(engineKey);
        dataValueBasicEngine.set(dataValue);
        dataValueBasicEngine.execution();
    }


    public void execution(String engineKey,DataValueRows dataValue){

        BasicEngine<DataValueRows> dataValueBasicEngine = engineDataSetMap.get(engineKey);
        dataValueBasicEngine.set(dataValue);
        dataValueBasicEngine.execution();
    }




}
