package com.yice.webadmin.app.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.pagehelper.Page;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.common.core.base.service.BaseService;
import com.yice.common.core.object.MyPageParam;
import com.yice.common.core.object.MyRelationParam;
import com.yice.common.core.util.MyModelUtil;
import com.yice.common.sequence.wrapper.IdGeneratorWrapper;
import com.yice.webadmin.app.constant.DatasetConstant;
import com.yice.webadmin.app.dao.DatasetCleanConfigMapper;
import com.yice.webadmin.app.dao.DatasetCleanMapper;
import com.yice.webadmin.app.data.*;
import com.yice.webadmin.app.model.DatasetClean;
import com.yice.webadmin.app.model.DatasetCleanConfig;
import com.yice.webadmin.app.model.DatasetVersion;
import com.yice.webadmin.app.service.DatasetCleanConfigService;
import com.yice.webadmin.app.service.DatasetCleanService;
import com.yice.webadmin.app.service.DatasetDataService;
import com.yice.webadmin.app.service.DatasetVersionService;
import com.yice.webadmin.app.util.DataCleanerUtil;
import com.yice.webadmin.app.util.JsonNameExtractor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * 数据集详情数据操作服务类。
 *
 * @author linking
 * @date 2023-04-13
 */
@Slf4j
@Service("datasetCleanService")
public class DatasetCleanServiceImpl extends BaseService<DatasetClean, Long> implements DatasetCleanService {

    @Autowired
    private DatasetCleanMapper datasetCleanMapper;
    @Autowired
    private DatasetCleanConfigMapper datasetCleanConfigMapper;
    @Autowired
    private IdGeneratorWrapper idGenerator;
    @Autowired
    private DatasetCleanConfigService datasetCleanConfigService;
    @Autowired
    private DatasetDataService datasetDataService;
    @Autowired
    private DatasetVersionService datasetVersionService;

    /**
     * 返回当前Service的主表Mapper对象。
     *
     * @return 主表Mapper对象。
     */
    @Override
    protected BaseDaoMapper<DatasetClean> mapper() {
        return datasetCleanMapper;
    }

    /**
     * 保存新增对象。
     *
     * @param datasetClean 新增对象。
     * @return 返回新增对象。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public DatasetClean saveNew(DatasetClean datasetClean) {
        datasetCleanMapper.insert(this.buildDefaultValue(datasetClean));
        return datasetClean;
    }

    /**
     * 保存清洗对象以及清洗配置对象。
     *
     * @param datasetClean 新增对象。
     * @return 返回新增对象。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public DatasetClean addNew(DatasetClean datasetClean) {
        datasetClean.setCleanStatus(DatasetConstant.CLEAN_PROGRESS);
        datasetClean.setStartTime(new Date());
        datasetClean.setCleanType(DatasetConstant.CLEAN_TYPE);
        datasetCleanMapper.insert(this.buildDefaultValue(datasetClean));

        DatasetCleanConfig datasetCleanConfig = datasetClean.getConfig();
        if(null != datasetCleanConfig) {
            datasetCleanConfig.setCleanId(datasetClean.getCleanId());
            datasetCleanConfig.setCleanConfigId(idGenerator.nextLongId());
            MyModelUtil.fillCommonsForInsert(datasetCleanConfig);
            datasetCleanConfigMapper.insert(datasetCleanConfig);
        }

        updateVersionStatus(datasetClean.getDatasetId(),DatasetConstant.CLEAN_PROGRESS);
        datasetDataService.doDatasetCleanHandler(datasetClean.getDatasetId(), datasetClean.getCleanId());
        return datasetClean;
    }

    /**
     * 线程方法
     * @param dataList 数据集列表
     * @param cleanId 清洗标识
     * @param datasetId 清洗集标识
     * @return 线程方法
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Future<Long> executeCleanTaskAsync(List<DatasetData> dataList, Long cleanId, Long datasetId) {
        asyncDealWithDatasetSaveBatch(dataList, cleanId);
        dealWithTaskHandler(datasetId,cleanId);
        updateCleanStatus(cleanId,DatasetConstant.CLEAN_FINISHED);
        updateVersionStatus(datasetId,DatasetConstant.CLEAN_FINISHED);
        return new AsyncResult<>(cleanId);
    }

    /**
     * 更新版本状态
     * @param versionId 数据集标识
     * @param cleanStatus 清洗状态
     */
    private void updateVersionStatus(Long versionId, Integer cleanStatus) {
        DatasetVersion filter = new DatasetVersion();
        filter.setVersionId(versionId);
        filter.setCleanStatus(cleanStatus);
        this.datasetVersionService.updateById(filter);
    }

    /**
     * 更新清洗状态
     * @param cleanId 清洗标识
     */
    private void updateCleanStatus (Long cleanId,Integer cleanStatus) {
        DatasetClean filter = new DatasetClean();
        filter.setCleanStatus(cleanStatus);
        filter.setFinishTime(new Date());
        filter.setCleanId(cleanId);
        this.updateById(filter);
    }

    /**
     * 只异步处理前100条数据清洗数据
     * @param dataList 清洗列表
     * @param cleanId 清洗标识
     */
    private void asyncDealWithDatasetSaveBatch(List<DatasetData> dataList, Long cleanId) {
        List<DatasetDataClean> cleans = asyncCleanTaskHandler(dataList, cleanId);
        this.datasetCleanConfigService.saveDatasetClean(cleans);
        List<DatasetDataFilter> filters =  asyncFilterTaskHandler(dataList, cleanId);
        this.datasetCleanConfigService.saveDatasetFilter(filters);
        List<DatasetDataDeduplicate> deduplicates = asyncDeduplicateTaskHandler(dataList, cleanId);
        this.datasetCleanConfigService.saveDatasetDeduplicate(deduplicates);
        List<DatasetDataDesensitive> desensitives = asyncDesensitiveTaskHandler(dataList, cleanId);
        this.datasetCleanConfigService.saveDatasetDesensitive(desensitives);
    }

    /**
     * 停止清洗任务
     * @param cleanId 清洗任务id
     */
    @Override
    public void stopCleanTask(Long cleanId) {
        DatasetClean filter = this.datasetCleanMapper.selectById(cleanId);
        if(null != filter){
            updateCleanStatus(cleanId,DatasetConstant.PAUSE_FINISHED);
            updateVersionStatus(filter.getDatasetId(),DatasetConstant.PAUSE_FINISHED);
        }
    }

    /**
     * 重新清洗任务
     * @param cleanId 清洗任务id
     */
    @Override
    public void restartCleanTask(Long cleanId) {
        DatasetClean clean = this.datasetCleanMapper.selectById(cleanId);
        if(null != clean){
            datasetDataService.doDatasetCleanHandler(clean.getDatasetId(), cleanId);
            updateCleanStatus(cleanId,DatasetConstant.CLEAN_PROGRESS);
            updateVersionStatus(clean.getDatasetId(),DatasetConstant.CLEAN_PROGRESS);
        }
    }

    /**
     * ==============================
     * ===总数据清洗过程===
     * 1、分页处理每页10000条数据
     * 2、更新Mongodb数据库中的数据
     * 3、更新json存储地址的数据集数据
     * 4、更新版本数据集状态
     * ==============================
     * 处理数据集
     * @param cleanId 清洗任务id
     * @return 清洗列表
     */
    private void dealWithTaskHandler(Long datasetId, Long cleanId) {
        try {
            DatasetVersion datasetVersion = this.datasetVersionService.getById(datasetId);
            datasetVersionService.saveDatasetInfo(datasetVersion.getVersionName());
            clearFileDatasetData(datasetVersion.getFileUrl());

            //记录是否有追加数据
            Integer index = 0;
            Long count = datasetDataService.count(datasetId);
            if (count > 0) {
                List<DatasetRule> rules = buildRulesList(cleanId);
                int pageSize = DatasetConstant.MAX_SIZE;
                int totalPages = (int) Math.ceil((double) count / pageSize);
                MyPageParam param;
                for (int i = 1; i <= totalPages; i++) {
                    param = new MyPageParam();
                    param.setPageNum(i);
                    param.setPageSize(pageSize);
                    List<DatasetData> dataList = datasetDataService.list(datasetId, param);

                    //写入到数据集中
                    List<DatasetData> newDataList = dealWithDatasetNodeData(dataList, datasetId, rules);
                    if(CollUtil.isNotEmpty(newDataList)) {
                        appendDataListToFile(datasetVersion.getFileUrl() ,newDataList, i);
                        index ++;
                    }
                }

                //解析文件去掉多余的数据，比如文件里面最后一个，多加了一个",",缺少符号[]
                if(index > 0){
                    readJsonAppendSymbol(datasetVersion.getFileUrl());
                }

                //删除为空的数据集数据
                this.datasetDataService.deleteByData(datasetId);
            }
        } catch (Exception ex) {
            log.error("deal with task handler is error:" , ex);
        }
    }

    /**
     * 构建规则列表
     * @param cleanId 清洗标识
     * @return 规则列表
     */
    private List<DatasetRule> buildRulesList(Long cleanId) {
        DatasetCleanConfig cleanConfig = new DatasetCleanConfig();
        cleanConfig.setCleanId(cleanId);
        DatasetCleanConfig datasetCleanConfig = datasetCleanConfigService.getOne(cleanConfig);

        List<DatasetRule> rules = new ArrayList<>();
        if(null != datasetCleanConfig) {
            String[] nonEmptyJsonStrings = {datasetCleanConfig.getFilterConfig(),datasetCleanConfig.getDesensitiveConfig(),
                                    datasetCleanConfig.getDesensitiveConfig(),datasetCleanConfig.getDeduplicateConfig(),
                                    datasetCleanConfig.getCleanConfig()};

            String[] jsonStrings = Arrays.stream(nonEmptyJsonStrings)
                    .map(Optional::ofNullable)
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .toArray(String[]::new);

            ObjectMapper objectMapper = new ObjectMapper();
            rules = Arrays.stream(jsonStrings)
                    .map(jsonString -> {
                        try {
                            return objectMapper.readValue(jsonString, DatasetRule[].class);
                        } catch (JsonProcessingException e) {
                            log.error("json processing exception is error:", e);
                            return null;
                        }
                    })
                    .flatMap(Arrays::stream)
                    .collect(Collectors.toList());
        }
        return rules;
    }

    /**
     * 第一个方法：清空文件
     * @param filePath 文件地址
     */
    public void clearFileDatasetData(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            FileWriter fileWriter = null;
            try {
                fileWriter = new FileWriter(file, true);
                fileWriter.write("");
            } catch (IOException e) {
                log.error("clearFileDatasetData method is error:", e);
            } finally {
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (IOException e) {
                        log.error("file write close is errot", e);
                    }
                }
            }
        }
    }

    /**
     * 解析文件去掉多余的数据，比如文件里面最后一个，多加了一个",",缺少符号[]
     * @param filePath 文件地址
     */
    @Override
    public void readJsonAppendSymbol(String filePath) {
        try (FileReader fileReader = new FileReader(filePath);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            StringBuilder jsonBuilder = new StringBuilder();
            String line;
            boolean isFirstLine = true;

            while ((line = bufferedReader.readLine()) != null) {
                if (isFirstLine) {
                    jsonBuilder.append("[");
                    isFirstLine = false;
                } else {
                    // Add comma before each element except the first
                    jsonBuilder.append("\n");
                }
                jsonBuilder.append(line);
            }

            // Remove last comma if present
            if (jsonBuilder.charAt(jsonBuilder.length() - 1) == ',') {
                jsonBuilder.deleteCharAt(jsonBuilder.length() - 1);
            }

            // Add closing bracket
            jsonBuilder.append("]");

            // Write the modified JSON data back to the file
            try (FileWriter fileWriter = new FileWriter(filePath);
                 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
                bufferedWriter.write(jsonBuilder.toString());
            }
        } catch (IOException e) {
            log.error("io exception is error:",e);
        }
    }

    /**
     * 第二个方法：将数据列表追加到文件
     * @param filePath 文件地址
     * @param dataList 数据集列表
     */
    @Override
    public void appendDataListToFile(String filePath, List<DatasetData> dataList,Integer pageNum) {
        FileWriter fileWriter = null;
        try {
            //为第一页的情况下
            if(pageNum == 1) {
                // 清空文件内容
                File file = new File(filePath);
                if (file.exists()) {
                    // 删除文件
                    file.delete();
                }
                // 创建一个新的空文件
                file.createNewFile();
            }

            fileWriter = new FileWriter(filePath, true);
            // 遍历你的数据列表，并将每一条数据写入到文件中
            for (DatasetData data : dataList) {
                if(StringUtils.isNotBlank(data.getData())) {
                    fileWriter.write(data.getData() + ",");
                    fileWriter.write("\n");
                }
            }
        } catch (IOException e) {
            log.error("file write close is error", e);
        } finally {
            // 如果fileWriter不为空，关闭它
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    log.error("file write close is error", e);
                }
            }
        }
    }

    /**
     * 处理data节点中的
     * @param dataList 数据集列表
     * @param datasetId 数据集标识
     * @param rules 规则列表
     */
    private List<DatasetData> dealWithDatasetNodeData(List<DatasetData> dataList,
                                                      Long datasetId, List<DatasetRule> rules) {
        List<DatasetData> newDataList = new ArrayList<>();
        try {
            if(CollUtil.isNotEmpty(dataList)) {

                ObjectMapper objectMapper = new ObjectMapper();
                for (DatasetData datasetData : dataList) {
                    JsonNode rootNode = objectMapper.readTree(datasetData.getData());
                    String data = rootNode.get(DatasetConstant.OUTPUT).textValue();
                    String output = DataCleanerUtil.buildCleanAfterData(data, rules);

                    //校验清洗后的数据是否满足条件，如果满足条件，则进行添加，否则直接移除。
                    if(StringUtils.isNotBlank(output)) {
                        datasetData.setData(createNewDataNode(datasetData.getData(), output));
                    }else {
                        datasetData.setData(DatasetConstant.NULL_STR);
                    }
                    newDataList.add(datasetData);
                }

                //批量添加数据集列表
                this.datasetDataService.updateBatch(newDataList, datasetId);
            }
        }catch (JsonProcessingException ex){
            log.error("deal with dataset node data:", ex);
        }
        return newDataList;
    }

    /**
     * 创建新的数据节点
     * @param json Json对象
     * @param output 输出对象
     * @return 新的data数据
     * @throws JsonProcessingException 转换异常
     */
    private String createNewDataNode(String json, String output) throws JsonProcessingException{
        String modifiedJson = null;
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(json);

        // 检查output字段是否存在
        if (rootNode.has(DatasetConstant.OUTPUT)) {

            // 转换root节点为ObjectNode以便修改
            ObjectNode objectNode = (ObjectNode) rootNode;

            // 替换output字段的值
            objectNode.put(DatasetConstant.OUTPUT, output);

            // 将修改后的JSON转换回字符串
            modifiedJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectNode);

        }
        return modifiedJson;
    }

    /**
     * ===异常清洗===
     * 处理数据集
     * @param dataList 清洗数据集列表
     * @param cleanId 清洗任务id
     *
     * @return 清洗列表
     */
    private List<DatasetDataClean> asyncCleanTaskHandler(List<DatasetData> dataList, Long cleanId) {
        List<DatasetDataClean> cleans = new ArrayList<>();
        try {
            DatasetCleanConfig filter = new DatasetCleanConfig();
            filter.setCleanId(cleanId);
            DatasetCleanConfig cleanConfig = datasetCleanConfigService.getOne(filter);
            if(null != cleanConfig && null == cleanConfig.getCleanConfig()) return cleans;

            if(CollUtil.isNotEmpty(dataList)) {
                ObjectMapper objectMapper = new ObjectMapper();
                DatasetRule[] datasetRules = objectMapper.readValue(cleanConfig.getCleanConfig(), DatasetRule[].class);
                List<DatasetRule> rules = Arrays.asList(datasetRules);

                for(DatasetData datasetData: dataList) {
                    DatasetDataClean dataClean = new DatasetDataClean();
                    JsonNode rootNode = objectMapper.readTree(datasetData.getData());
                    String data = rootNode.get(DatasetConstant.OUTPUT).textValue();
                    dataClean.setCleanBeforeData(data);

                    String cleanAfterData = DataCleanerUtil.buildCleanAfterData(data,rules);
                    if(StringUtils.isEmpty(cleanAfterData) || data.equals(cleanAfterData)) continue;

                    dataClean.setCleanAfterData(cleanAfterData);
                    dataClean.setCleanId(cleanId);
                    dataClean.setCreateTime(new Date());
                    cleans.add(dataClean);
                }
            }
        } catch (Exception ex) {
            log.error("Async clean task handler is error:" , ex);
        }
        return cleans;
    }

    /**
     * ===隐私清洗===
     * 处理数据集
     * @param dataList 清洗数据集列表
     * @param cleanId 清洗任务id
     * @return 清洗列表
     */
    private List<DatasetDataDesensitive> asyncDesensitiveTaskHandler(List<DatasetData> dataList, Long cleanId) {
        List<DatasetDataDesensitive> desensitives = new ArrayList<>();
        try {
            DatasetCleanConfig filter = new DatasetCleanConfig();
            filter.setCleanId(cleanId);
            DatasetCleanConfig desenstiveCfg = datasetCleanConfigService.getOne(filter);
            if(null != desenstiveCfg && null == desenstiveCfg.getDesensitiveConfig()) return desensitives;

            if(CollUtil.isNotEmpty(dataList)) {
                ObjectMapper objectMapper = new ObjectMapper();
                DatasetRule[] datasets = objectMapper.readValue(desenstiveCfg.getDesensitiveConfig(), DatasetRule[].class);
                List<DatasetRule> rules = Arrays.asList(datasets);

                for(DatasetData datasetData: dataList) {
                    DatasetDataDesensitive desensitive = new DatasetDataDesensitive();
                    JsonNode node = objectMapper.readTree(datasetData.getData());
                    String data = node.get(DatasetConstant.OUTPUT).textValue();

                    String cleanAfterData = DataCleanerUtil.buildCleanAfterData(data,rules);
                    if(StringUtils.isEmpty(cleanAfterData) || data.equals(cleanAfterData)) continue;

                    desensitive.setCleanBeforeData(data);
                    desensitive.setCleanAfterData(cleanAfterData);
                    desensitive.setCleanId(cleanId);
                    desensitive.setCreateTime(new Date());
                    desensitives.add(desensitive);
                }
            }
        } catch (Exception ex) {
            log.error("Async desensitive task handler is error:" , ex);
        }
        return desensitives;
    }

    /**
     * ===去重清洗===
     * 处理数据集
     * @param dataList 清洗数据集列表
     * @param cleanId 清洗任务id
     * @return 清洗列表
     */
    private List<DatasetDataDeduplicate> asyncDeduplicateTaskHandler(List<DatasetData> dataList, Long cleanId) {
        List<DatasetDataDeduplicate> deduplicates = new ArrayList<>();
        try {
            DatasetCleanConfig filter = new DatasetCleanConfig();
            filter.setCleanId(cleanId);
            DatasetCleanConfig deduplicateConfig = datasetCleanConfigService.getOne(filter);
            if(null != deduplicateConfig && null == deduplicateConfig.getDeduplicateConfig()) return deduplicates;

            if(CollUtil.isNotEmpty(dataList)) {
                ObjectMapper objectMapper = new ObjectMapper();
                DatasetRule[] datasetRules = objectMapper.readValue(deduplicateConfig.getDeduplicateConfig(), DatasetRule[].class);
                List<DatasetRule> rules = Arrays.asList(datasetRules);

                for(DatasetData datasetData: dataList) {
                    DatasetDataDeduplicate deduplicate = new DatasetDataDeduplicate();
                    JsonNode jsonNode = objectMapper.readTree(datasetData.getData());
                    String data = jsonNode.get(DatasetConstant.OUTPUT).textValue();

                    String cleanAfterData = DataCleanerUtil.buildCleanAfterData(data,rules);
                    if(StringUtils.isEmpty(cleanAfterData) || data.equals(cleanAfterData)) continue;

                    deduplicate.setCleanBeforeData(data);
                    deduplicate.setCleanAfterData(cleanAfterData);
                    deduplicate.setCleanId(cleanId);
                    deduplicate.setCreateTime(new Date());
                    deduplicates.add(deduplicate);
                }
            }
        } catch (Exception ex) {
            log.error("Async deduplicate task handler is error:" , ex);
        }
        return deduplicates;
    }

    /**
     * ===过滤清洗===
     * 处理数据集
     * @param dataList 清洗数据集列表
     * @param cleanId 清洗任务id
     * @return 清洗列表
     */
    private List<DatasetDataFilter> asyncFilterTaskHandler(List<DatasetData> dataList, Long cleanId) {
        List<DatasetDataFilter> filters = new ArrayList<>();
        try {
            DatasetCleanConfig filter = new DatasetCleanConfig();
            filter.setCleanId(cleanId);
            DatasetCleanConfig filterConfig = datasetCleanConfigService.getOne(filter);
            if(null != filterConfig && null == filterConfig.getFilterConfig()) return filters;

            if(CollUtil.isNotEmpty(dataList)) {
                ObjectMapper objectMapper = new ObjectMapper();
                DatasetRule[] datasetRules = objectMapper.readValue(filterConfig.getFilterConfig(), DatasetRule[].class);
                List<DatasetRule> rules = Arrays.asList(datasetRules);

                for(DatasetData datasetData: dataList) {
                    DatasetDataFilter dataFilter = new DatasetDataFilter();
                    dataFilter.setCleanId(cleanId);
                    dataFilter.setCreateTime(new Date());
                    JsonNode rootNode = objectMapper.readTree(datasetData.getData());
                    String data = rootNode.get(DatasetConstant.OUTPUT).textValue();

                    String cleanAfterData = DataCleanerUtil.buildCleanAfterData(data,rules);
                    if(StringUtils.isEmpty(cleanAfterData) || data.equals(cleanAfterData)) continue;

                    dataFilter.setCleanBeforeData(data);
                    dataFilter.setCleanAfterData(cleanAfterData);
                    filters.add(dataFilter);
                }
            }
        } catch (Exception ex) {
            log.error("Async filter task handler is error:" , ex);
        }
        return filters;
    }

    /**
     * 利用数据库的insertList语法，批量插入对象列表。
     *
     * @param datasetCleanList 新增对象列表。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveNewBatch(List<DatasetClean> datasetCleanList) {
        if (CollUtil.isNotEmpty(datasetCleanList)) {
            datasetCleanList.forEach(this::buildDefaultValue);
            datasetCleanMapper.insertList(datasetCleanList);
        }
    }

    /**
     * 更新数据对象。
     *
     * @param datasetClean         更新的对象。
     * @param originalDatasetClean 原有数据对象。
     * @return 成功返回true，否则false。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean update(DatasetClean datasetClean, DatasetClean originalDatasetClean) {
        MyModelUtil.fillCommonsForUpdate(datasetClean, originalDatasetClean);
        // 这里重点提示，在执行主表数据更新之前，如果有哪些字段不支持修改操作，请用原有数据对象字段替换当前数据字段。
        UpdateWrapper<DatasetClean> uw = this.createUpdateQueryForNullValue(datasetClean, datasetClean.getCleanId());
        return datasetCleanMapper.update(datasetClean, uw) == 1;
    }

    /**
     * 删除指定数据。
     *
     * @param cleanId 主键Id。
     * @return 成功返回true，否则false。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean remove(Long cleanId) {
        return datasetCleanMapper.deleteById(cleanId) == 1;
    }

    /**
     * 获取单表查询结果。由于没有关联数据查询，因此在仅仅获取单表数据的场景下，效率更高。
     * 如果需要同时获取关联数据，请移步(getDatasetCleanListWithRelation)方法。
     *
     * @param filter  过滤对象。
     * @param orderBy 排序参数。
     * @return 查询结果集。
     */
    @Override
    public List<DatasetClean> getDatasetCleanList(DatasetClean filter, String orderBy) {
        return datasetCleanMapper.getDatasetCleanList(filter, orderBy);
    }

    /**
     * 获取主表的查询结果，以及主表关联的字典数据和一对一从表数据，以及一对一从表的字典数据。
     * 该查询会涉及到一对一从表的关联过滤，或一对多从表的嵌套关联过滤，因此性能不如单表过滤。
     * 如果仅仅需要获取主表数据，请移步(getDatasetCleanList)，以便获取更好的查询性能。
     *
     * @param filter  主表过滤对象。
     * @param orderBy 排序参数。
     * @return 查询结果集。
     */
    @Override
    public List<DatasetClean> getDatasetCleanListWithRelation(DatasetClean filter, String orderBy) {
        List<DatasetClean> resultList = datasetCleanMapper.getDatasetCleanList(filter, orderBy);
        // 在缺省生成的代码中，如果查询结果resultList不是Page对象，说明没有分页，那么就很可能是数据导出接口调用了当前方法。
        // 为了避免一次性的大量数据关联，规避因此而造成的系统运行性能冲击，这里手动进行了分批次读取，开发者可按需修改该值。
        int batchSize = resultList instanceof Page ? 0 : 1000;
        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
        this.buildDatasetMethod(resultList);
        return resultList;
    }

    /**
     * 构建数据集方法
     * @param datasetCleanList 数据清洗列表
     */
    private void buildDatasetMethod(List<DatasetClean> datasetCleanList){
        List<String> jsonStrings = new ArrayList<>();
        if(CollUtil.isNotEmpty(datasetCleanList)){
            for(DatasetClean datasetClean: datasetCleanList) {
                DatasetCleanConfig filter = new DatasetCleanConfig();
                filter.setCleanId(datasetClean.getCleanId());
                DatasetCleanConfig cleanConfig = datasetCleanConfigService.getOne(filter);

                if(null != cleanConfig) {
                    jsonStrings.add(cleanConfig.getCleanConfig());
                    jsonStrings.add(cleanConfig.getDeduplicateConfig());
                    jsonStrings.add(cleanConfig.getFilterConfig());
                    jsonStrings.add(cleanConfig.getDesensitiveConfig());
                    List<String> nonEmptyJsonStrings = jsonStrings.stream()
                            .filter(s -> s != null && !s.isEmpty()).collect(Collectors.toList());
                    datasetClean.setCleanMethod(JsonNameExtractor.extractNames(nonEmptyJsonStrings));
                }
            }
        }
    }

    /**
     * 新增清理对象
     * @param DatasetClean 数据集清理对象
     * @return 清理对象
     */
    private DatasetClean buildDefaultValue(DatasetClean DatasetClean) {
        if (DatasetClean.getCleanId() == null) {
            DatasetClean.setCleanId(idGenerator.nextLongId());
        }
        MyModelUtil.fillCommonsForInsert(DatasetClean);
        return DatasetClean;
    }
}
