package com.sunxung.factoring.component.util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description:TODO这里用一句话描述这个类的作用
 * @Author:wanxiangZhou
 * @E_mail:303526821@qq.com
 * @Date:2017年5月4日 下午4:50:24
 */
public class FormulaParser {

    /**
     * 匹配变量占位符的正则表达式
     */
    private static Pattern pattern = Pattern.compile("\\#\\{(.+?)\\}");

    /**
     * 解析公式，并执行公式计算. <br/>
     * 
     * @param formula
     * @param formulas
     * @param values
     * @return
     */
    public static BigDecimal parse(String formula, Map<String, String> formulas, Map<String, BigDecimal> values) {
        if (formulas == null || formula == "")
            formulas = Collections.emptyMap();
        if (values == null)
            values = Collections.emptyMap();
        String expression = finalExpression(formula, formulas, values);
        return new Calculator().eval(expression);
    }

    private static String finalExpression(String expression, Map<String, String> formulas,
            Map<String, BigDecimal> values) {
        Matcher m = pattern.matcher(expression);
        if (!m.find())
            return expression;
        m.reset();
        StringBuffer buffer = new StringBuffer();
        while (m.find()) {
            String group = m.group(1);
            System.out.println("解析的参数：" + group);
            if (formulas != null && formulas.containsKey(group)) {
                String formula = formulas.get(group);
                m.appendReplacement(buffer, '(' + formula + ')');
            } else if (values != null && values.containsKey(group)) {
                BigDecimal value = values.get(group);
                if (null == value) {
                    value = new BigDecimal(0);
                }
                m.appendReplacement(buffer, value.toPlainString());
            } else {
                throw new IllegalArgumentException("expression '" + expression + "' has a illegal variable:" + m.group()
                        + ",cause veriable '" + group + "' not being found in formulas or in values.");
            }
        }
        m.appendTail(buffer);
        return finalExpression(buffer.toString(), formulas, values);
    }

    /**
     * 提取表达式里面的ID
     *
     * @param expression 例如公式："(#{2}+20)*#{24}+13-#{2}+24";
     * @return List<Long> 返回#{}里面的内容的数字
     */
    public static List<Long> parseExpressionSpecial(String expression) {
        List<Long> list = new ArrayList<>();
        Matcher m = pattern.matcher(expression);
        if (!m.find())
            return null;
        m.reset();
        while (m.find()) {
            String group = m.group(1);
            list.add(Long.valueOf(group));
            // System.out.println("解析的参数：" + group);
        }
        return list;
    }

    /**
     * 提取表达式里面的数字
     *
     * @param expression 例如公式："(#{2}+20)*#{24}+13-#{2}+24";
     * @return List<Long> 返回所有的数字里面的内容的数字
     */
    public static List<Long> parseExpressionObtainNum(String expression) {
        Pattern pattern = Pattern.compile("\\d+");
        List<Long> list = new ArrayList<>();
        Matcher m = pattern.matcher(expression);
        if (!m.find())
            return null;
        m.reset();
        while (m.find()) {
            String group = m.group(0);
            list.add(Long.valueOf(group));
        }
        return list;
    }

    public static void main(String[] args) {
        String expression2 = "(#{2})*#{24}+13-#{2}+24";
        List<Long> list = FormulaParser.parseExpressionObtainNum(expression2);
        // java8版本
        list.forEach(item -> {
            System.out.println(item.longValue());
        });
    }
}
