package com.ruoyi.generator.util;

import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.generator.domain.Datasource;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;

import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DataBaseTools {
    /**
     * 获取数据库连接
     *
     * @param dataSource
     * @return
     */
    public static Connection getConn(Datasource dataSource) {
        Connection conn = null;
        try {
            Class.forName(dataSource.getDriver());
            conn = DriverManager.getConnection(dataSource.getUrl(), dataSource.getUser(), dataSource.getPassword());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭数据库连接
     *
     * @param rs
     * @param stm
     * @param conn
     */
    public static void closeConn(ResultSet rs, Statement stm, Connection conn) {
        try {
            if (rs != null)
                rs.close();
            if (stm != null)
                stm.close();
            if (conn != null)
                conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试数据库连接
     *
     * @param dataSource
     * @return
     */
    public static int testConnection(Datasource dataSource) {
        Connection conn = null;
        ResultSet rs = null;
        Statement st = null;
        int data = 0;
        String sql = "select 1";
        try {
            conn = getConn(dataSource);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            if (rs.next()) {
                data = rs.getInt(1);
            }
        } catch (Exception e) {
            return data;
        } finally {
            closeConn(rs, st, conn);
        }
        return data;
    }

    /**
     * 获取数据库表信息
     *
     * @param dataSource
     * @return
     */
    public static List<GenTable> getTable(Datasource dataSource) {
        List<GenTable> list = new ArrayList<>();
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        Connection conn = null;
        ResultSet rs = null;
        Statement st = null;
        GenTable table;
        String sql = "select table_name, table_comment, create_time, update_time from information_schema.tables \n" +
                "  where table_schema = (select database()) \n" +
                "  AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%' LIMIT " + ((pageNum-1)  * pageSize) + "," + pageSize;
        try {
            conn = getConn(dataSource);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            while (rs.next()) {
                table = new GenTable();
                table.setTableName(rs.getString(1));
                table.setTableComment(rs.getString(2));
                table.setCreateTime(rs.getDate(3));
                table.setUpdateTime(rs.getDate(4));
                list.add(table);
            }
        } catch (Exception e) {
            return list;
        } finally {
            closeConn(rs, st, conn);
        }
        return list;
    }

    /**
     * 获取数据库表信息
     *
     * @param dataSource
     * @return
     */
    public static List<GenTable> getTableByName(String[] tableNames, Datasource dataSource) {
        List<GenTable> list = new ArrayList<>();
        Connection conn = null;
        ResultSet rs = null;
        Statement st = null;
        GenTable table;
        String sql = "select table_name, table_comment, create_time, update_time from information_schema.tables \n" +
                "  where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) \n" +
                "  and table_name in " + Arrays.toString(tableNames).replace(", ", "','").replace("[", "('").replace("]", "')") ;
        try {
            conn = getConn(dataSource);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            while (rs.next()) {
                table = new GenTable();
                table.setTableName(rs.getString(1));
                table.setTableComment(rs.getString(2));
                table.setCreateTime(rs.getDate(3));
                table.setUpdateTime(rs.getDate(4));
                list.add(table);
            }
        } catch (Exception e) {
            return list;
        } finally {
            closeConn(rs, st, conn);
        }
        return list;
    }

    /**
     * 获取数据库表信息
     *
     * @param dataSource
     * @return
     */
    public static List<GenTableColumn> getTableColumnByName(String tableName, Datasource dataSource) {
        List<GenTableColumn> list = new ArrayList<>();
        Connection conn = null;
        ResultSet rs = null;
        Statement st = null;
        GenTableColumn tableColumn;
        String sql = "select column_name, (case when (is_nullable = 'no' && column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type\n" +
                "  from information_schema.columns where table_schema = (select database()) and table_name = ('"+tableName+"')\n" +
                "  order by ordinal_position";
        try {
            conn = getConn(dataSource);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            while (rs.next()) {
                tableColumn = new GenTableColumn();
                tableColumn.setColumnName(rs.getString(1));
                tableColumn.setIsRequired(rs.getString(2));
                tableColumn.setIsPk(rs.getString(3));
                tableColumn.setSort(rs.getInt(4));
                tableColumn.setColumnComment(rs.getString(5));
                tableColumn.setIsIncrement(rs.getString(6));
                tableColumn.setColumnType(rs.getString(7));
                list.add(tableColumn);
            }
        } catch (Exception e) {
            return list;
        } finally {
            closeConn(rs, st, conn);
        }
        return list;
    }

    public static long getTableCount(Datasource datasource) {
        long total = 0L;
        Connection conn = null;
        ResultSet rs = null;
        Statement st = null;
        GenTable table;
        String sql = "select count(1) from information_schema.tables \n" +
                "  where table_schema = (select database()) \n" +
                "  AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'";
        try {
            conn = getConn(datasource);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            while (rs.next()) {
                total = rs.getInt(1);
            }
        } catch (Exception e) {
            return total;
        } finally {
            closeConn(rs, st, conn);
        }
        return total;
    }

    /**
     * 获取数据表的建表语句
     *
     * @param tableName 表名
     * @param dataSource 数据源
     * @return 建表语句
     */
    public static String getTableCreateSql(String tableName, Datasource dataSource) {
        String createSql = "";
        Connection conn = null;
        ResultSet rs = null;
        Statement st = null;
        String sql = "SHOW CREATE TABLE `" + tableName + "`";
        try {
            conn = getConn(dataSource);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            if (rs.next()) {
                createSql = rs.getString(2); // 建表语句在结果集的第二列
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeConn(rs, st, conn);
        }
        return createSql;
    }
}
