package com.zt.plat.module.qms;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.jupiter.api.Test;

import com.alibaba.qlexpress4.Express4Runner;
import com.alibaba.qlexpress4.InitOptions;
import com.alibaba.qlexpress4.QLOptions;
import com.alibaba.qlexpress4.security.QLSecurityStrategy;
import com.zt.plat.module.qms.core.qlexpress.function.RoundToScaleHalfEven;

public class QLExpressRunnerTest {
	
	@Test
	void roundToScaleTest() throws Exception {
//		ExpressRunner expressRunner = new ExpressRunner(true, false);
		Express4Runner express4Runner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
		express4Runner.addFunction("roundToScale", new RoundToScaleHalfEven());
		String express_3 = "roundToScale(0.2434, 3)";
//		Object result_3 = expressRunner.execute(express_3, null, null, false, false);
		Object result_3 = express4Runner.execute(express_3, new HashMap<>(), QLOptions.DEFAULT_OPTIONS).getResult();
		
		System.out.println("四舍0.2434 ：" + result_3);
		String express_4 = "roundToScale(0.2416, 3)";
//		Object result_4 = expressRunner.execute(express_4, null, null, false, false);
		Object result_4 = express4Runner.execute(express_4, new HashMap<>(), QLOptions.DEFAULT_OPTIONS).getResult();
		System.out.println("六入0.2416 ：" + result_4);
		String express_1 = "roundToScale(0.2445, 3)";
//		Object result_1 = expressRunner.execute(express_1, null, null, false, false);
		Object result_1 = express4Runner.execute(express_1, new HashMap<>(), QLOptions.DEFAULT_OPTIONS).getResult();
		System.out.println("偶不变0.2445 ：" + result_1);
		String express_2 = "roundToScale(0.2455, 3)";
//		Object result_2 = expressRunner.execute(express_2, null, null, false, false);
		Object result_2 = express4Runner.execute(express_2, new HashMap<>(), QLOptions.DEFAULT_OPTIONS).getResult();
		System.out.println("奇变0.2455 ：" + result_2);
	}

	@Test
	void calculateAverageValueTest() throws Exception {
		//兼容3 将安全策略设置为 “开放”
		InitOptions initOptions = InitOptions.builder().securityStrategy(QLSecurityStrategy.open()).build();
		Express4Runner expressRunner = new Express4Runner(initOptions);
//		Express4Runner expressRunner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
		/**
		 String exp = ""
            + "function abc(int a, int b) {"
            + "    return a + b;"
            + "}"
            + "return abc(1 + 100, 2 * 100)";
        IExpressContext<String, Object> context = new DefaultContext<>();
        Object result = expressRunner.execute(exp, context, null, false, false);
        System.out.println(result);
        **/  
//
//		String express = """
//				function calculateAverageValue(values, elementScale) {
//				    if (values == null || values.size() == 0) return roundToScale(0, elementScale);
//				    if (values.size() == 1) return roundToScale(values.get(0), elementScale);
//				    sum = reduce(values, 0, "a + b");
//				    return roundToScale(sum / values.size(), elementScale);
//				}
//				calculateAverageValue(values, elementScale);
//				""";
		String express = """
				    if (values == null || values.size() == 0) return roundToScale(0, scale);
				    if (values.size() == 1) return roundToScale(values.get(0), scale);
				    sum = 0;
				    for(int i = 0; i < values.size(); i = i + 1) {
				    	sum = sum + values.get(i);
				    }
				    return roundToScale(sum / values.size(), scale);
				""";
		
		expressRunner.addFunction("roundToScale", new RoundToScaleHalfEven());
		
		List<BigDecimal> valuesList = new ArrayList<>();
//		valuesList.add(new BigDecimal("0.2445"));
//		valuesList.add(new BigDecimal("0.5435"));
//		valuesList.add(new BigDecimal("0.8436"));
		valuesList.add(new BigDecimal("2.05"));
		valuesList.add(new BigDecimal("2.05"));
		valuesList.add(new BigDecimal("0"));
		
		int elementScale = 2;
		
		Map<String, Object> context = new HashMap<>();
		context.put("values", valuesList);
		context.put("scale", elementScale);
//		Object result = expressRunner.execute(express, context, null, false, false);
		Object result = expressRunner.execute(express, context, QLOptions.DEFAULT_OPTIONS).getResult();
        System.out.println(result);
		result = expressRunner.execute(express, context, QLOptions.builder().precise(true).build()).getResult();
        System.out.println(result);
		

//        String[] names = expressRunner.getOutVarNames(express);
        Set<String> outVarNames = expressRunner.getOutVarNames(express);
		for(String s: outVarNames){
		    System.out.println("var : " + s);
		}
	}
}
