package com.kingdee.eas.custom.dataconfig.utils;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.util.TablesNamesFinder;

import java.util.*;


public class NativeSqlJoinOptimizer {

    public  String cleanRedundantJoins(String originalSql)   throws JSQLParserException {
        // 1. 解析SQL
        Statement statement = CCJSqlParserUtil.parse(originalSql);
        Select select = (Select) statement;
        PlainSelect plainSelect = (PlainSelect) select.getSelectBody();

        // 2. 提取所有被使用的表名（用内置工具类，更稳定）
        Set<String> usedTables = getUsedTables(plainSelect);
        System.out.println("被使用的表：" + usedTables); // 输出 [t1, t2]

        // 3. 过滤冗余JOIN
        List<Join> filteredJoins = new ArrayList<>();
        if (plainSelect.getJoins() != null) {
            for (Join join : plainSelect.getJoins()) {
                if (join.getRightItem() instanceof Table) {
                    Table joinTable = (Table) join.getRightItem();
                    String tableName = joinTable.getName();
                    if (usedTables.contains(tableName)) {
                        filteredJoins.add(join);
                    }
                }
            }
        }

        // 4. 重构SQL
        plainSelect.setJoins(filteredJoins);
        String optimizedSql = plainSelect.toString();
        System.out.println("优化后的SQL：" + optimizedSql);
        return optimizedSql;
    }

    /**
     * 提取使用的表名（不依赖SelectExpressionItem）
     */
    private static Set<String> getUsedTables(PlainSelect plainSelect) {
        Set<String> usedTables = new HashSet<>();
        TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();

        // 1. 提取主表（FROM）
        if (plainSelect.getFromItem() instanceof Table) {
            Table fromTable = (Table) plainSelect.getFromItem();
            usedTables.add(fromTable.getName());
        }

        // 2. 提取SELECT字段中的表（遍历Column，直接获取表名）
        for (SelectItem item : plainSelect.getSelectItems()) {
            // 直接遍历Item中的Column，绕过SelectExpressionItem
            item.accept(new SelectItemVisitorAdapter() {
                public void visit(Column column) {
                    if (column.getTable() != null) {
                        usedTables.add(column.getTable().getName());
                    }
                }
            });
        }

        // 3. 提取WHERE条件中的表（用内置工具类）
        if (plainSelect.getWhere() != null) {
            List<String> whereTables = tablesNamesFinder.getTableList(plainSelect.getWhere());
            usedTables.addAll(whereTables);
        }

        return usedTables;
    }


}
