package com.muyu.rule.server.controller;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.muyu.common.core.domain.Result;

import com.muyu.etl.domain.DataValue;
import com.muyu.rule.common.constant.SuffixClass;
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.domain.req.VersionAddReq;
import com.muyu.rule.common.utils.LoadEngineClass;
import com.muyu.rule.common.utils.OssUtil;
import com.muyu.rule.server.service.RuleEngineVersionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * @Author：张承志
 * @Package：com.muyu.rule.server.controller
 * @Project：cloud-etl-rule
 * @name：RuleEngineVersionController
 * @Date：2024/8/25 10:41
 */
@Log4j2
@RestController
@RequestMapping("/version")
@RequiredArgsConstructor
@Tag(name = "规则版本控制层", description = "规则版本管理,查看等相关操作")
public class RuleEngineVersionController {

    /**
     * 保存代码
     * @param ruleEngineVersion
     * @return
     */
    @PostMapping("/saveCode")
    @Operation(summary = "通过id回显规则版本",description = "传入规则版本的主键id,返回规则版本的对象")
    public Result saveCode(@RequestBody RuleEngineVersion ruleEngineVersion){

        log.info("==>"+ruleEngineVersion.getVersionClazz());
        UpdateWrapper<RuleEngineVersion> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",ruleEngineVersion.getId()).set("version_clazz",ruleEngineVersion.getVersionClazz());
        versionService.update(updateWrapper);
        //删除对应oss上的类
        OssUtil.deliteOssClient(ruleEngineVersion.getClassName()+SuffixClass.Suffix_CLASS);
        //编译并上传
        versionService.complierClass(ruleEngineVersion.getClassName(),ruleEngineVersion.getVersionClazz());

        return   Result.success();
    }

    @PostMapping("/findVersionById/{id}")
    @Operation(summary = "通过id回显规则版本",description = "传入规则版本的主键id,返回规则版本的对象")
    public Result<RuleEngineVersion>findVersionById(@PathVariable("id") Long id){

        RuleEngineVersion ruleEngineVersion = versionService.getById(id);

        return Result.success(ruleEngineVersion);
    }



    @Autowired
    private RuleEngineVersionService versionService;

    /**
     * 添加规则引擎版本
     * @param versionAddReq 引擎版本添加实体类
     * @return
     */
 @PostMapping("/insertVersion")
 @Operation(summary = "增加规则引擎版本",description = "通过传入版本添加的实体类,进行规则引擎的版本添加")
    public Result insertVersion(@Validated @RequestBody VersionAddReq versionAddReq){

     boolean save = versionService.save(RuleEngineVersion.addBuild(versionAddReq));
     if (true==save){
      //添加成功则把增加的代码进行java编译,进行热加载
         versionService.complierClass(versionAddReq.getClassName(),versionAddReq.getVersionClazz());
     }

     return  Result.success();
 }


 @PostMapping("/deliteVersionById/{id}")
 public Result deliteVersionById(@PathVariable("id") Long id){

     boolean b = versionService.removeById(id);

     RuleEngineVersion ruleEngineVersion = versionService.getById(id);
     if (true==b){
         OssUtil.deliteOssClient(ruleEngineVersion.getClassName()+SuffixClass.Suffix_CLASS);
     }
     return Result.success();
 }



    /**
     * 激活引擎请求
     * @param id
     * @return
     */
    @PostMapping("/activate/{id}")
    @Operation(summary = "规则引擎的激活", description = "通过Id激活规则引擎")
    public Result activate(@PathVariable("id") Long id){

        versionService.activate(id);

        return Result.success();
    }

    /**
     * 取消引擎请求
     */

    @PostMapping("/disable/{id}")
    @Operation(summary = "规则引擎的取消", description = "通过Id取消规则引擎")
    public Result disable(@PathVariable("id") Long id){

        versionService.disable(id);

        return Result.success();
    }



    /**
     * 生成代码
     * @param
     * @return
     */

    @PostMapping("/deposit/{type}")
    public Result deposit(@PathVariable("type") Integer type,
                          @Validated @RequestBody VersionAddReq versionAddReq) {

        log.info("传入参数{}", type);

        // 根据类型确定父类
        String parentClass = determineParentClass(type);
        String dataClass = determineDataClass(type);
        // 定义模板字符串
        String template = "package com.muyu.rule.common.engine;\n" +
                "\n" +
                "import com.muyu.etl.domain.DataValue;\n" +
                "import com.muyu.rule.common.domain.${dataClass};\n" +
                "import com.muyu.rule.common.basic.abstracts.${parentClass};\n" +
                "import com.muyu.rule.common.exception.DeliteException;\n" +
                "import com.alibaba.fastjson2.JSON;\n" +
                "import com.alibaba.fastjson2.JSONObject;\n"+
                "\n" +
                "\n" +
                "/**\n" +
                " * @Package：com.muyu.rule.server.basic.engine\n" +
                " * @Project：cloud-etl-rule\n" +
                " * @name：${className}\n" +
                " */\n" +
                "\n" +
                "public class ${className} extends ${parentClass} {\n" +
                "\n" +
                "    @Override\n" +
                "    public void run() {\n" +
                "    }\n" +
                "}\n";

        // 使用Map进行模板替换
        Map<String, String> replacements = Map.of(
                "${className}", versionAddReq.getClassName(),
                "${parentClass}", parentClass,
                "${dataClass}",dataClass
        );

        // 替换模板中的变量
        String versionClass = replacePlaceholders(template, replacements);

        versionAddReq.setVersionClazz(versionClass);

        return Result.success(versionAddReq);
    }

    // 辅助方法用于根据类型决定父类
    private String determineParentClass(Integer type) {
        switch (type) {
            case 1:
                return "DataEngineValueActuator";
            case 2:
                return "DataEngineRowActuator";
            case 3:
                return "DataEngineDataSetActuator";
            default:
                throw new IllegalArgumentException("Invalid type provided");
        }
    }
    private String determineDataClass(Integer type) {
        switch (type) {
            case 1:
                return "DataValueFie";
            case 2:
                return "DataValueRow";
            case 3:
                return "DataValueRows";
            default:
                throw new IllegalArgumentException("Invalid type provided");
        }
    }
    // 辅助方法用于替换模板中的占位符
    private String replacePlaceholders(String template, Map<String, String> replacements) {
        for (Map.Entry<String, String> entry : replacements.entrySet()) {
            template = template.replace(entry.getKey(), entry.getValue());
        }
        return template;
    }


    /**
     * 从oss读取数据
     * @param className
     * @return
     */

@PostMapping("/readByOss/{className}")
@Operation(summary = "从Oss获取数据", description = "传入参数oss的key名从oss读取数据")
    public Result readByOss(@PathVariable String className){

Object  o=  versionService.readByOss(className);

    return Result.success(o);
    }




    /**
     * 通过id查询对应的版本
     * @param id
     * @return
     */

@PostMapping("/selectVersionById/{id}")
public Result<List<RuleEngineVersion>> selectVersionById(@PathVariable("id") Long id){

    List<RuleEngineVersion> versionList = versionService.selectRuleEngineVersion(id);

    return Result.success(versionList);
}




    @Autowired
    private LoadEngineClass loadEngineClass;

    @PostMapping("/testEngine/{className}")
    @Operation(summary = "字段规则引擎测试", description = "传入规则引擎的类名,和数据,用规则引擎进行测试数据")
    public Result<DataValue> testEngine(@PathVariable("className") String className,@RequestBody DataValueFie dataValue){
        log.info("数据:" + dataValue);
        //加载对应的规则引擎
        loadEngineClass.loadValueEngineClass(className);
        //执行对应的规则引擎
        DataValue value = versionService.testEngine(className, dataValue);

        return Result.success(value);
    }

    @PostMapping("/rowEngine/{className}")
    @Operation(summary = "行/记录规则引擎测试", description = "传入规则引擎的类名,和数据,用规则引擎进行测试数据")
    public Result<DataValue[]> testEngine(@PathVariable("className") String className,@RequestBody DataValueRow dataValue){
        log.info("数据:" + dataValue);
        //加载对应的规则引擎
        loadEngineClass.loadRowEngineClass(className);
        //执行对应的规则引擎
        DataValue[] value = versionService.testEngine(className, dataValue);

        return Result.success(value);
    }
@PostMapping("/DataSetEngine/{className}")
@Operation(summary = "数据集的规则引擎测试", description = "传入规则引擎的类名,和数据,用规则引擎进行测试数据")
public Result<DataValue[][]> DataSetEngine(@PathVariable("className") String className,@RequestBody DataValueRows dataValues){

    loadEngineClass.loadDataSetEngineClass(className);

    DataValue[][] testedEngine = versionService.testEngine(className, dataValues);

    return Result.success(testedEngine);
}










}



