package com.hotent.util;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 从表达式提取参数变量
 */
public class VariableParser {

    /**
     * 从四则运算表达式中提取所有变量
     * @param expression 四则运算表达式
     * @return 变量名的Set集合
     */
    public static Set<String> extractVariables(String expression) {
        Set<String> variables = new HashSet<>();

        // 正则表达式：匹配变量名（字母或下划线开头，后跟字母、数字或下划线）
        Pattern pattern = Pattern.compile("[a-zA-Z_.][a-zA-Z0-9_.]*");
        Matcher matcher = pattern.matcher(expression);

        // JavaScript/数学函数和常量黑名单
        Set<String> blacklist = new HashSet<>(Arrays.asList(
                "Math", "math",
                "sin", "cos", "tan", "cot", "sec", "csc",
                "asin", "acos", "atan", "acot",
                "sinh", "cosh", "tanh",
                "log", "ln", "lg", "exp",
                "sqrt", "cbrt", "abs",
                "PI", "E", "pi", "e",
                "min", "max", "pow", "random"
        ));

        while (matcher.find()) {
            String potentialVar = matcher.group();

            // 检查是否是黑名单中的数学函数或常量
            if (!blacklist.contains(potentialVar)) {
                // 检查是否全是数字（虽然正则已经排除了以数字开头的情况，但确保安全）
                if (!potentialVar.matches("\\d+")) {
                    variables.add(potentialVar);
                }
            }
        }

        return variables;
    }

    /**
     * 提取变量并统计出现次数
     */
    public static Map<String, Integer> extractVariablesWithCount(String expression) {
        Map<String, Integer> variableCount = new HashMap<>();

        // 数学函数和常量黑名单
        Set<String> blacklist = new HashSet<>(Arrays.asList(
                "Math", "sin", "cos", "tan", "log", "sqrt", "PI", "E"
        ));

        Pattern pattern = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");
        Matcher matcher = pattern.matcher(expression);

        while (matcher.find()) {
            String potentialVar = matcher.group();

            if (!blacklist.contains(potentialVar) && !potentialVar.matches("\\d+")) {
                variableCount.put(potentialVar, variableCount.getOrDefault(potentialVar, 0) + 1);
            }
        }

        return variableCount;
    }

    public static void main(String[] args) {
        String[] testExpressions = {
                "(taiyuan.c1+taiyuan.c2)*(c1/c2)+c1",
                "a + b * c - d / e",
                "sin(x) + cos(y) + log(z)",
                "width * height + depth",
                "2 * PI * radius",
                "temp1 + temp2 - temp3 * temp4",
                "var_1 + var_2 * var_test"
        };

        for (String expr : testExpressions) {
            Set<String> variables = extractVariables(expr);
            Map<String, Integer> variableCount = extractVariablesWithCount(expr);

            System.out.println("表达式: " + expr);
            System.out.println("提取的变量: " + variables);
            System.out.println("变量出现次数: " + variableCount);
            System.out.println();
        }
    }
}
