package com.zkqy.datamodeling.service.impl;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.DataSourceType;
import com.ruoyi.common.constant.LoadDriverConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.DataSource;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import javax.sql.rowset.JdbcRowSet;

import com.sun.rowset.JdbcRowSetImpl;

import com.zkqy.datamodeling.domain.TableInfo;
import com.zkqy.datamodeling.domain.vo.TableInfoVO;
import com.zkqy.datamodeling.mapper.TableInfoMapper;
import com.zkqy.datamodeling.service.ITableInfoService;
import org.apache.ibatis.io.Resources;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TableInfoServiceImpl implements ITableInfoService {

    @Resource
    private TableInfoMapper tableInfoMapper;

    @Resource
    private RedisTemplate redisTemplate;

    //    @Value("${spring.datasource.dynamic.datasource.master.url}")
    private String url = "ry-vue";

    @Override
    @Transactional
    public void createMysqlTable(Map<String, Object> map) {
//        String dataBaseName = (String) map.get("dataBaseName");
        String tableName = (String) map.get("tableName");
        String tableComment = (String) map.get("tableComment");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }
            if (filed.getIsPrimary()) {
                stringBuilder.append("PRIMARY KEY ");
                if (filed.getIsAuto()) {
                    stringBuilder.append("AUTO_INCREMENT ");
                }
            }
            stringBuilder.append("COMMENT '" + filed.getFieldDescription() + "'");
            return stringBuilder.toString();
        }).collect(Collectors.toList());
        tableInfoMapper.createMysqlTable(tableName, tableComment, list);
    }

    @Override
    @Transactional
    public void createSqlServerDataBase(Map<String, Object> map) {
//        DataSource dataSource = JSON.parseObject(redisTemplate.opsForValue().get("DataSource").toString(),DataSource.class);
//        String dataBaseName = (String) map.get("dataBaseName");
        String tableName = (String) map.get("tableName");
        String tableComment = (String) map.get("tableComment");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }
            if (filed.getIsPrimary()) {
                stringBuilder.append("PRIMARY KEY ");
                if (filed.getIsAuto()) {
                    stringBuilder.append("IDENTITY(1,1) ");
                }
            }
            return stringBuilder.toString();
        }).collect(Collectors.toList());

        List<String> descriptionList = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            if (StringUtils.hasLength(filed.getFieldDescription())) {
                stringBuilder.append("EXECUTE sp_addextendedproperty N'MS_Description',")
                        .append("'" + filed.getFieldDescription() + "'")
                        .append(", N'user', N'dbo', N'table', N")
                        .append("'" + tableName + "'")
                        .append(", N'column', N")
                        .append("'" + filed.getFieldName() + "'");
            }
            return stringBuilder.toString();
        }).collect(Collectors.toList());
//        if(dataBaseName.equals(dataSource.getDatabaseName())){
//            tableInfoMapper.createSqlServerDataBase(dataBaseName);
//            tableInfoMapper.createSqlServerTable(dataBaseName,tableName,list,descriptionList,tableComment);
//        }else {
//            tableInfoMapper.createSqlServerDataBase(dataBaseName);
//            tableInfoMapper.useSqlserverDatabase(dataBaseName);
        tableInfoMapper.createSqlServerTable(tableName, list, descriptionList, tableComment);
//            tableInfoMapper.useSqlserverDatabase(dataSource.getDatabaseName());
//        }

    }

    @Override
    public int mysqlTableExist(String dataBaseName, String tableName) {
        return tableInfoMapper.mysqlTableExist(dataBaseName, tableName);
    }

    @Override
    public AjaxResult tableInfoList(Map<String, Object> map) {
        int pageNum = Integer.valueOf(map.get("pageNum").toString());
        int pageSize = Integer.valueOf(map.get("pageSize").toString());
        String databaseType = (String) map.get("databaseType");
        String databaseName = (String) map.get("databaseName");
        String username = (String) map.get("username");

        if (!StringUtils.hasLength(databaseType)) {
            return AjaxResult.error("当前用户没有数据源,无法查看该页面");
        }

        //获取数据源信息
//        if(redisTemplate.hasKey("DataSource")){
//            DataSource dataSource =JSON.parseObject(redisTemplate.opsForValue().get("DataSource").toString(),DataSource.class);
        if (databaseType.equals(DataSourceType.MYSQL.getDataSourceName())) {
            List<TableInfoVO> mysqlTableList = tableInfoMapper.tableInfoList(databaseName, map);
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.put("code", 200)
                    .put("data", mysqlTableList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).
                            collect(Collectors.toList()))
                    .put("msg", "操作成功")
                    .put("total", mysqlTableList.size());
            return ajaxResult;

        } else if (databaseType.equals(DataSourceType.SQLSERVER.getDataSourceName())) {
            List<TableInfoVO> sqlServerTableList = tableInfoMapper.sqlServerTableInfoList(databaseName, map);
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.put("code", 200)
                    .put("data", sqlServerTableList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).
                            collect(Collectors.toList()))
                    .put("msg", "操作成功")
                    .put("total", sqlServerTableList.size());
            return ajaxResult;

        } else if (databaseType.equals(DataSourceType.DM.getDataSourceName())) {
            List<TableInfoVO> dmTableList = tableInfoMapper.dmTableInfoList(databaseName, map);
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.put("code", 200)
                    .put("data", dmTableList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).
                            collect(Collectors.toList()))
                    .put("msg", "操作成功")
                    .put("total", dmTableList.size());
            return ajaxResult;
        } else if (databaseType.equals(DataSourceType.ORACLE.getDataSourceName())) {
            List<TableInfoVO> dmTableList = tableInfoMapper.oracleTableInfoList(username, map);
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.put("code", 200)
                    .put("data", dmTableList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).
                            collect(Collectors.toList()))
                    .put("msg", "操作成功")
                    .put("total", dmTableList.size());
            return ajaxResult;
        }
//        }
        List<TableInfoVO> mysqlTableList = tableInfoMapper.tableInfoList(databaseName, map);
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("code", 200)
                .put("data", mysqlTableList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).
                        collect(Collectors.toList()))
                .put("msg", "操作成功")
                .put("total", mysqlTableList.size());
        return ajaxResult;

    }

    @Override
    public int selectDataCount(String tableName) {
        return tableInfoMapper.selectDataCount(tableName);
    }

    @Override
    public AjaxResult dropTable(Map<String, Object> map) {
        String tableName = (String) map.get("tableName");
        String databaseType = (String) map.get("databaseType");
        String databaseName = (String) map.get("databaseName");
//        if(redisTemplate.hasKey("DataSource")){
//            DataSource dataSource = JSON.parseObject(redisTemplate.opsForValue().get("DataSource").toString(),DataSource.class);
        if (databaseType.equals(DataSourceType.MYSQL.getDataSourceName())) {
            if (tableInfoMapper.selectDataCount(tableName) > 0) {
                return AjaxResult.warn("表中有数据,不能删除!");
            }
            tableInfoMapper.dropMysqlTable(tableName);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.SQLSERVER.getDataSourceName())) {
            if (tableInfoMapper.selectSqlServerDataCount(tableName) > 0) {
                return AjaxResult.warn("表中有数据,不能删除!");
            }
            tableInfoMapper.dropSqlserverTable(tableName);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.DM.getDataSourceName())) {
            if (tableInfoMapper.selectDmDataCount(tableName) > 0) {
                return AjaxResult.warn("表中有数据,不能删除!");
            }
            tableInfoMapper.dropDmTable(databaseName, tableName);
            return AjaxResult.success();
        }

//        }
        if (tableInfoMapper.selectDataCount(tableName) > 0) {
            return AjaxResult.warn("表中有数据,不能删除!");
        }
        tableInfoMapper.dropMysqlTable(tableName);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult createTable(Map<String, Object> map) {
        String dataBaseName = (String) map.get("dataBaseName");
        String tableName = (String) map.get("tableName");
        String databaseType = (String) map.get("databaseType");
        if (databaseType.equals(DataSourceType.MYSQL.getDataSourceName())) {
            if (tableInfoMapper.mysqlTableExist(dataBaseName, tableName) > 0) {
                return AjaxResult.warn("当前数据库中表已存在");
            }
            createMysqlTable(map);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.SQLSERVER.getDataSourceName())) {
            if (sqlServerTableExist(dataBaseName, tableName) > 0) {
                return AjaxResult.warn("当前数据库中表已存在");
            }
            createSqlServerDataBase(map);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.DM.getDataSourceName())) {
            if (tableInfoMapper.dmTableExist(dataBaseName, tableName) > 0) {
                return AjaxResult.warn("当前数据库中表已存在");
            }
            createDmDataBase(map);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.ORACLE.getDataSourceName())) {
            if (tableInfoMapper.oracleTableExist(tableName) > 0) {
                return AjaxResult.warn("当前数据库中表已存在");
            }
            createOracleTable(map);
            return AjaxResult.success();
        }
        if (tableInfoMapper.mysqlTableExist(dataBaseName, tableName) > 0) {
            return AjaxResult.warn("当前数据库中表已存在");
        }
        createMysqlTable(map);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult updateTable(Map<String, Object> map) {
        String dataBaseName = (String) map.get("databaseName");
        String databaseType = (String) map.get("databaseType");
        String tableName = (String) map.get("tableName");
//        if(redisTemplate.hasKey("DataSource")){
//            DataSource dataSource = JSON.parseObject(redisTemplate.opsForValue().get("DataSource").toString(),DataSource.class);
        if (databaseType.equals(DataSourceType.MYSQL.getDataSourceName())) {
            if (tableInfoMapper.selectDataCount(tableName) > 0) {
                return AjaxResult.warn("表中有数据,不能删除!");
            }
            updateMysqlTable(map);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.SQLSERVER.getDataSourceName())) {
            if (tableInfoMapper.selectSqlServerDataCount(tableName) > 0) {
                return AjaxResult.warn("表中有数据,不能删除!");
            }
            updateSqlserverTable(map);
            return AjaxResult.success();
        } else if (databaseType.equals(DataSourceType.DM.getDataSourceName())) {
            if (tableInfoMapper.selectDmDataCount(tableName) > 0) {
                return AjaxResult.warn("表中有数据,不能删除!");
            }
            map.put("dataBaseName", dataBaseName);
            updateDmTable(map);
            return AjaxResult.success();
        }
//        }
        if (tableInfoMapper.selectDataCount(tableName) > 0) {
            return AjaxResult.warn("表中有数据,不能删除!");
        }
        updateMysqlTable(map);
        return AjaxResult.success();
    }

    @Override
    public List<TableInfo> tableFieldInfo(Map<String, Object> map) {

        String tableName = (String) map.get("tableName");
        String databaseType = (String) map.get("databaseType");
        String databaseName = (String) map.get("databaseName");
//        if(redisTemplate.hasKey("DataSource")){
//            DataSource dataSource =JSON.parseObject(redisTemplate.opsForValue().get("DataSource").toString(),DataSource.class);
        if (databaseType.equals(DataSourceType.MYSQL.getDataSourceName())) {
            return tableInfoMapper.mysqlTableFieldInfo(databaseName, tableName);
        } else if (databaseType.equals(DataSourceType.SQLSERVER.getDataSourceName())) {
            return tableInfoMapper.sqlserverTableFieldInfo(tableName);
        } else if (databaseType.equals(DataSourceType.DM.getDataSourceName())) {
            return tableInfoMapper.dmTableFieldInfo(databaseName, tableName);
        }
//        }
        return tableInfoMapper.mysqlTableFieldInfo(databaseName, tableName);
    }

    @Override
    public void updateMysqlTable(Map<String, Object> map) {
        String tableName = (String) map.get("tableName");
        String tableComment = (String) map.get("tableComment");
        String databaseName = (String) map.get("databaseName");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }
            if (filed.getIsPrimary()) {
                stringBuilder.append("PRIMARY KEY ");
                if (filed.getIsAuto()) {
                    stringBuilder.append("AUTO_INCREMENT ");
                }
            }
            stringBuilder.append("COMMENT '" + filed.getFieldDescription() + "'");
            return stringBuilder.toString();
        }).collect(Collectors.toList());

        // 暂存要删除的表sql
        String backupSql = tableInfoMapper.backupTableSql(databaseName, tableName).get("Create Table");
        try {
            tableInfoMapper.updateMysqlTable(databaseName, tableName, tableComment, list);
        } catch (Exception e) {
            // 恢复修改前数据表
            tableInfoMapper.executeCreateTableSql(backupSql);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

    }

    @Override
    public int sqlServerTableExist(String dataBaseName, String tableName) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(dataBaseName)
                .append(".dbo.")
                .append(tableName);
        return tableInfoMapper.sqlServerTableExist(stringBuilder.toString());
    }

    @Override
    public int selectSqlServerDataCount(String tableName) {
        return tableInfoMapper.selectSqlServerDataCount(tableName);
    }

    @Override
    public void dropSqlserverTable(String tableName) {
        tableInfoMapper.dropSqlserverTable(tableName);
    }

    @Override
    public void updateSqlserverTable(Map<String, Object> map) {
        String tableName = (String) map.get("tableName");
        String tableComment = (String) map.get("tableComment");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }
            if (filed.getIsPrimary()) {
                stringBuilder.append("PRIMARY KEY ");
                if (filed.getIsAuto()) {
                    stringBuilder.append("IDENTITY(1,1) ");
                }
            }
            return stringBuilder.toString();
        }).collect(Collectors.toList());

        List<String> descriptionList = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            if (StringUtils.hasLength(filed.getFieldDescription())) {
                stringBuilder.append("EXECUTE sp_addextendedproperty N'MS_Description',")
                        .append("'" + filed.getFieldDescription() + "'")
                        .append(", N'user', N'dbo', N'table', N")
                        .append("'" + tableName + "'")
                        .append(", N'column', N")
                        .append("'" + filed.getFieldName() + "'");
            }
            return stringBuilder.toString();
        }).collect(Collectors.toList());
        // 删除表
        tableInfoMapper.dropSqlserverTable(tableName);
        // 新增表
        tableInfoMapper.updateSqlserverTable(tableName, list, descriptionList, tableComment);
    }

    @Override
    public int dmTableExist(String dataBaseName, String tableName) {
        return tableInfoMapper.dmTableExist(dataBaseName, tableName);
    }

    @Override
    public void createDmDataBase(Map<String, Object> map) {
        String databaseName = (String) map.get("databaseName");
        String tableName = (String) map.get("tableName");
        String tableComment = (String) map.get("tableComment");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> descriptionList = new ArrayList<>();
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsPrimary()) {
                if (filed.getIsAuto()) {
                    stringBuilder.append("IDENTITY(1,1) ");
                }
                stringBuilder.append("PRIMARY KEY ");
            }
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }

            if (StringUtils.hasLength(filed.getFieldDescription())) {
                StringBuilder builder = new StringBuilder();
                builder.append("COMMENT ON COLUMN \"")
                        .append(databaseName)
                        .append("\".\"")
                        .append(tableName)
                        .append("\".\"")
                        .append(filed.getFieldName() + "\" IS ")
                        .append("'" + filed.getFieldDescription() + "'");
                descriptionList.add(builder.toString());
            }

            return stringBuilder.toString();
        }).collect(Collectors.toList());

        tableInfoMapper.createDmTable(databaseName, tableName, list);
        descriptionList.stream().forEach(f -> tableInfoMapper.addTableDescription(f));
        tableInfoMapper.addDmTableComment(databaseName, tableName, tableComment);
    }

    @Override
    public void updateDmTable(Map<String, Object> map) {
        String databaseName = (String) map.get("databaseName");
        String tableName = (String) map.get("tableName");
        String tableComment = (String) map.get("tableComment");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> descriptionList = new ArrayList<>();
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsPrimary()) {
                if (filed.getIsAuto()) {
                    stringBuilder.append("IDENTITY(1,1) ");
                }
                stringBuilder.append("PRIMARY KEY ");
            }
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }

            if (StringUtils.hasLength(filed.getFieldDescription())) {
                StringBuilder builder = new StringBuilder();
                builder.append("COMMENT ON COLUMN \"")
                        .append(databaseName)
                        .append("\".\"")
                        .append(tableName)
                        .append("\".\"")
                        .append(filed.getFieldName() + "\" IS ")
                        .append("'" + filed.getFieldDescription() + "'");
                descriptionList.add(builder.toString());
            }

            return stringBuilder.toString();
        }).collect(Collectors.toList());
        tableInfoMapper.dropDmTable(databaseName, tableName);
        tableInfoMapper.createDmTable(databaseName, tableName, list);
        descriptionList.stream().forEach(f -> tableInfoMapper.addTableDescription(f));
        tableInfoMapper.addDmTableComment(databaseName, tableName, tableComment);

    }

    @Override
    public int oracleTableExist(String tableName) {
        return tableInfoMapper.oracleTableExist(tableName);
    }

    @Override
    public void createOracleTable(Map<String, Object> map) {
        String tableName = (String) map.get("tableName");
        List<TableInfo> filedList = JSON.parseArray(JSON.toJSONString(map.get("field")), TableInfo.class);
        List<String> descriptionList = new ArrayList<>();
        List<String> list = filedList.stream().map(filed -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(filed.getFieldName() + " ")
                    .append(filed.getFieldType() + " ");
            if (filed.getIsPrimary()) {
                stringBuilder.append("PRIMARY KEY ");
            }
            if (filed.getIsNull()) {
                stringBuilder.append("NOT NULL ");
            }
            if (StringUtils.hasLength(filed.getFieldDescription())) {
                StringBuilder builder = new StringBuilder();
                builder.append("comment on column ")
                        .append(tableName)
                        .append(".")
                        .append(filed.getFieldName() + " is '")
                        .append(filed.getFieldDescription() + "'");
                descriptionList.add(builder.toString());
            }
            return stringBuilder.toString();
        }).collect(Collectors.toList());
        tableInfoMapper.createOracleTable(tableName, list);
        descriptionList.stream().forEach(f -> tableInfoMapper.addOracleTableDescription(f));
    }


//    @Override
//    public int initDatabase(DataSource dataSource) {
//        RestTemplate restTemplate = new RestTemplate();
//        // 得到基础模版库的连接信息
//        String result = restTemplate.getForObject(dictIp + dataSource.getDatabaseType() + "_connection_information", String.class);
//        Map<String, Object> objectMap = (Map<String, Object>) JSON.parse(result);
//        List<Map<String, Object>> dictList = (List<Map<String, Object>>) objectMap.get("data");
//        // 封住基础模版库的信息
//        DataSource dataSource2 = new DataSource();
//        try {
//            aa();
//            //this.asd();
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
////        for (Map<String, Object> map : dictList) {
////            switch (map.get("dictLabel").toString()) {
////                case "databaseName":
////                    dataSource2.setDatabaseName(map.get("dictValue").toString());
////                    break;
////                case "databaseIp":
////                    dataSource2.setDatabaseIp(map.get("dictValue").toString());
////                    break;
////                case "username":
////                    dataSource2.setUsername(map.get("dictValue").toString());
////                    break;
////                case "password":
////                    dataSource2.setPassword(map.get("dictValue").toString());
////                    break;
////                case "portNumber":
////                    dataSource2.setPortNumber(Long.parseLong(map.get("dictValue").toString()));
////                    break;
////                case "databaseType":
////                    dataSource2.setDatabaseType(map.get("dictValue").toString());
////                    break;
////                // 如果还有其他字段需要处理，可以继续添加case分支
////                default:
////                    break;
////            }
////        }
////
////        // 得到数据源信息 创建连接后进行创建数据库，以及基础数据表
////        switch (dataSource.getDatabaseType()) {
////            case "mysql":
////                // 创建数据库
////                tableInfoMapper.createMysqlDataBase(dataSource.getDatabaseName());
////                // 读取基础表信息
////
////                // /system/dict/data/type/{dictType}
////
////
////                // 查询主库中字典数据源信息
////
////
////                // 创建所需的基础表
////                List<String> sd = new ArrayList<>();
////                tableInfoMapper.createMysqlTable("表名", "表描述", sd);
////
////
////                break;
////            case "sqlserver":
////                tableInfoMapper.createSqlServerDataBase(dataSource.getDatabaseName());
////
////                // tableInfoMapper.createSqlServerTable();
////                break;
////            case "dm":
////                tableInfoMapper.createDmDataBase(dataSource.getDatabaseName());
////                break;
////            case "oracle":
////                tableInfoMapper.createOracleUser(dataSource.getUsername(), dataSource.getPassword());
////                break;
////        }
//        return 1;
//    }


    // 查询字典中的基础库模版信息
    @Value("${parameter.ip.MAIN_DICTIONARY_IP}")
    private String dictIp;

    @Override
    public AjaxResult initDatabase(DataSource dataSource) {
        RestTemplate restTemplate = new RestTemplate();
        //创建连接
        Connection tenantCon;
        Statement tenantSt;
        String driverName = null;
        String dbURL = null;
        String userName = dataSource.getUsername();
        String userPwd = dataSource.getPassword();
        // 基础模版信息库
        String foundationDriverName = null;
        String foundationDBURL = "";
        String foundationUserName = "";
        String foundationUserPwd = "";
        String foundationSQL = "";
        String foundationENDSQL = "";

        //查询数据库sql
        String showDatabaseSql = null;
        //创建数据库
        String createDatabaseSql = null;
        // 基础模版信息
        Map<String, Object> infoMap = new HashMap<>();
        // 得到mysql的基础数据表模版
        String ret = restTemplate.getForObject(dictIp + dataSource.getDatabaseType() + "_connection_information", String.class);
        // 得到基础模版库的连接信息
        Map<String, List<Map<String, Object>>> retMap = (Map<String, List<Map<String, Object>>>) JSON.parse(ret);
        retMap.get("data").forEach(item ->
        {
            infoMap.put(item.get("dictLabel").toString(), item.get("dictValue"));
        });
        //判断数据源，初始化对应创建信息
        switch (dataSource.getDatabaseType()) {
            case "mysql":
                driverName = LoadDriverConstants.MYSQL;
                dbURL = "jdbc:mysql://" + dataSource.getDatabaseIp() + ":" + dataSource.getPortNumber();
                showDatabaseSql = "show DATABASES";
                createDatabaseSql = "CREATE DATABASE IF NOT EXISTS `" + dataSource.getDatabaseName() + "` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;";
                // 封装mysql基础库信息连接信息
                foundationDriverName = "com.mysql.cj.jdbc.Driver";
                foundationDBURL += "jdbc:mysql://" + infoMap.get("databaseIp") + ":" + infoMap.get("portNumber") + "/" + infoMap.get("databaseName") + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
                foundationUserName += infoMap.get("username");
                foundationUserPwd += infoMap.get("password");
                foundationSQL += "SHOW TABLES;";
                foundationENDSQL += "SHOW CREATE TABLE `" + infoMap.get("databaseName") + "`.`tableName`";


                break;
            case "sqlserver":
                driverName = LoadDriverConstants.SQLSERVER;
                dbURL = "jdbc:sqlserver://" + dataSource.getDatabaseIp() + ":" + dataSource.getPortNumber() + ";DatabaseName=;trustServerCertificate=true;";
                showDatabaseSql = "select name from sys.databases";
                createDatabaseSql = "CREATE DATABASE " + dataSource.getDatabaseName();
                // 封装sqlserver基础库信息连接信息
                foundationDriverName = driverName;
                foundationDBURL += "jdbc:sqlserver://" + infoMap.get("databaseIp") + ":" + infoMap.get("portNumber") + ";DatabaseName=" + infoMap.get("databaseName") + ";trustServerCertificate=true;";
                foundationUserName += infoMap.get("username");
                foundationUserPwd += infoMap.get("password");
                break;
            case "dm":
                driverName = LoadDriverConstants.DM;
                dbURL = "jdbc:dm://" + dataSource.getDatabaseIp() + ":" + dataSource.getPortNumber();
                showDatabaseSql = "select name from sysobjects where TYPE$='sch' and SUBTYPE$ is null";
                createDatabaseSql = "CREATE SCHEMA " + dataSource.getDatabaseName();
                // 封装dm基础库信息连接信息
                foundationDriverName = driverName;
                foundationDBURL += "jdbc:dm://" + infoMap.get("databaseIp") + ":" + infoMap.get("portNumber") + "?schema=" + infoMap.get("databaseName");
                foundationUserName += infoMap.get("username");
                foundationUserPwd += infoMap.get("password");
                break;
            case "oracle":
                driverName = LoadDriverConstants.ORACLE;
                dbURL = "jdbc:oracle:thin:@" + dataSource.getDatabaseIp() + ":" + dataSource.getPortNumber();
                // 封装oracle基础库信息连接信息
                foundationDriverName = driverName;
                foundationDBURL += "jdbc:oracle:thin:@" + infoMap.get("databaseIp") + ":" + infoMap.get("portNumber") + ":" + dataSource.getDatabaseName();
                foundationUserName += infoMap.get("username");
                foundationUserPwd += infoMap.get("password");
                break;
            // 如果还有其他字段需要处理，可以继续添加case分支
            default:
                break;
        }
        try {
            // 建立数据源连接
            Class.forName(driverName);
            tenantCon = DriverManager.getConnection(dbURL, userName, userPwd);
            tenantSt = tenantCon.createStatement();
            //查询所有数据库
            ResultSet tenantRs = tenantSt.executeQuery(showDatabaseSql);
            while (tenantRs.next()) {//如果对象中有数据，就会循环打印出来
                System.out.println(tenantRs.getString(1));
                if (tenantRs.getString(1).equals(dataSource.getDatabaseName())) {
                    return AjaxResult.warn("数据库已存在!");
                }
            }
            //创建数据库
            tenantSt.executeUpdate(createDatabaseSql);
            // 建立连接查询得到所有表以及所有表信息
            Class.forName(foundationDriverName);
            Connection foundationCon = DriverManager.getConnection(foundationDBURL, foundationUserName, foundationUserPwd);
            Statement foundationSt = foundationCon.createStatement();
            // mysql 数据库执行查库
            if (dataSource.getDatabaseType().equals("mysql")) {

                //查询当前库中的所有表信息
                ResultSet foundationRs = foundationSt.executeQuery(foundationSQL);

                List<String> tableNameList = new ArrayList<>();
                // 封装数据，执行创建表操作
                while (foundationRs.next()) {
                    // 得到结果集->表名称
                    tableNameList.add(foundationRs.getString(1));
                }
                // 选择执行的sql语句
                tenantSt.executeUpdate("USE `" + dataSource.getDatabaseName() + "`");
                for (int i = 0; i < tableNameList.size(); i++) {
                    // 根据表名得到当前表结构信息
                    ResultSet structureRs = foundationSt.executeQuery(foundationENDSQL.replace("tableName", tableNameList.get(i)));
                    while (structureRs.next()) {
                        // 增加租户基础表
                        tenantSt.executeUpdate(structureRs.getString(2));
                    }
                }
                // 关闭连接
                foundationRs.close();
            } else {
                // 指定要执行的SQL脚本文件
                String sqlScript = "";
                switch (dataSource.getDatabaseType()) {
                    case "sqlserver":
                        sqlScript = "zkqy-datamodeling\\src\\main\\resources\\sql\\sqlserver.sql";
                        break;
                    case "dm":
                        sqlScript = "zkqy-datamodeling\\src\\main\\resources\\sql\\dm.sql";
                        break;
                    case "oracle":
                        sqlScript = "zkqy-datamodeling\\src\\main\\resources\\sql\\oracle.sql";
                        break;
                }
                // 读取SQL脚本文件
                BufferedReader reader = new BufferedReader(new FileReader(sqlScript));
                StringBuffer script = new StringBuffer();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    script.append(line.replaceAll("zkqy-call", dataSource.getDatabaseName()));
                    script.append(System.lineSeparator());
                }
                reader.close();
                if (dataSource.getDatabaseType().equals("dm")) {
                    foundationSt.execute("set schema " + dataSource.getDatabaseName() + ";");
                }
                if (dataSource.getDatabaseType().equals("sqlserver")) {
                    foundationSt.executeUpdate("USE " + dataSource.getDatabaseName() + ";");
                }
                // 将SQL脚本内容作为字符串执行
                foundationSt.executeUpdate(script.toString());
            }
            // 其他的数据类型则执行sql脚本文件
            foundationSt.close();
            foundationCon.close();
            // 关闭数据库连接
            tenantRs.close();
            tenantSt.close();
            tenantCon.close();

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.warn("初始化数据库异常，请确保连接信息无误！");
        }
        return AjaxResult.success();
    }
}