package org.springblade.datasource.transform;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.exception.ServiceException;
import org.springblade.datasource.enums.DsTypeEnum;
import org.springblade.datasource.support.DynamicDataSourceSupport;
import org.springblade.datasource.transform.postgresql.PostgreSQLParseTableHandle;
import org.springblade.datasource.transform.util.ListUtils;
import org.springblade.etl.entity.bi.ReportDatasource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * @author 喜欢番茄火锅
 * @date 2023/12/25 15:37
 */
@Slf4j
public abstract class JdbcCreartTableAbstract {
    /**
     * 根据通用表信息创建表对象
     *
     * @param tableInfo
     * @param targetDatasource
     * @return
     * @author 王瑞
     * @date 2023/8/21
     */
    @SneakyThrows
    public void creatTable(TableInfo tableInfo, ReportDatasource targetDatasource) {

        tableInfo.setTableName(tableInfo.getTableName().toUpperCase(Locale.ROOT));

        String columSql = buildColumnSql(tableInfo, targetDatasource);
        log.info("创建表sql 语句,sql:{}", columSql);

        String tableCommentSql = buildTableCommentSql(tableInfo, targetDatasource);
        log.info("创建表注释sql 语句,sql:{}", tableCommentSql);

        List<String> columnCommentSql = buildColumnCommentSql(tableInfo, targetDatasource);
        log.info("创建字段注释sql 语句,sql:{}", columnCommentSql);

        List<String> indexSql = buildIndexSql(tableInfo, targetDatasource);
        log.info("创建表索引sql 语句,sql:{}", indexSql);

        Connection connection = DynamicDataSourceSupport.createConnection(targetDatasource);
        Statement statement = connection.createStatement();

        ResultSet tables = connection.getMetaData().getTables(null, targetDatasource.getDbSchema(), tableInfo.getTableName(), new String[]{"TABLE", "VIEW"});
        if (tables.next()) {
            fieldComparison(tableInfo, targetDatasource, connection);
            return;
        }

        statement.executeUpdate(columSql);
        statement.executeUpdate(tableCommentSql);
        for (String s : columnCommentSql) {
            statement.executeUpdate(s);
        }
        for (String s : indexSql) {
            statement.executeUpdate(s);
        }
        statement.close();


    }

    protected void fieldComparison(TableInfo tableInfo, ReportDatasource targetDatasource, Connection connection) throws SQLException {
        List<ColumnInfo> sourceColumn = new PostgreSQLParseTableHandle().getSourceColumn(tableInfo.getTableName(), connection.getMetaData(), targetDatasource.getDbSchema());
        List<String> collect = tableInfo.getColumnInfo().stream().map(ColumnInfo::getColumnName).collect(Collectors.toList());
        List<String> collect2 = sourceColumn.stream().map(ColumnInfo::getColumnName).collect(Collectors.toList());
        if (!ListUtils.equalLists(collect, collect2)) {
            throw new ServiceException(DsTypeEnum.resolve(targetDatasource.getDsType()).name() + " 数据源,表名称:" + tableInfo.getTableName() + "已存在且字段不符!");
        }
    }


    protected abstract String buildColumnSql(TableInfo tableInfo, ReportDatasource targetDatasource);

    protected abstract String buildTableCommentSql(TableInfo tableInfo, ReportDatasource targetDatasource);

    protected abstract List<String> buildColumnCommentSql(TableInfo tableInfo, ReportDatasource targetDatasource);

    protected abstract List<String> buildIndexSql(TableInfo tableInfo, ReportDatasource targetDatasource);

}
