package com.syjy.calculate.listener;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Options;
import com.googlecode.aviator.runtime.JavaMethodReflectionFunctionMissing;
import com.syjy.calculate.function.*;
import com.syjy.calculate.repository.CalculationFormulaRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * 监听项目启动
 *
 * @author zcl
 * @version 1.0
 * @since 2022/9/9 10:34
 */
@Component
public class ApplicationListenerImpl implements ApplicationListener<ApplicationStartedEvent> {

    @Autowired
    private CalculationFormulaRepository calculationFormulaRepository;

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        // 初始化表
        calculationFormulaRepository.initTable();
        // 启用基于反射的方法查找和调用
        AviatorEvaluator.setFunctionMissing(JavaMethodReflectionFunctionMissing.getInstance());
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
        AviatorEvaluator.addFunction(new DoubleList());
        AviatorEvaluator.addFunction(new GetBeginOfDay());
        AviatorEvaluator.addFunction(new MeanAbsoluteError());
        AviatorEvaluator.addFunction(new Pass());
        AviatorEvaluator.addFunction(new PointS());
        AviatorEvaluator.addFunction(new PointU());
        AviatorEvaluator.addFunction(new RootMeanSquaredErrorA());
        AviatorEvaluator.addFunction(new RootMeanSquaredErrorC());
        AviatorEvaluator.addFunction(new RootMeanSquaredErrorR());
        AviatorEvaluator.addFunction(new RootMeanSquaredErrorS());
        AviatorEvaluator.addFunction(new RootMeanSquaredErrorSouthernPowerGrid());
        AviatorEvaluator.addFunction(new SumDifferenceAbsolute());
        AviatorEvaluator.addFunction(new SumDifferenceSquare());
        AviatorEvaluator.addFunction(new DevianceElectric());


        // |预测-可用|/预测
        AviatorEvaluator.defineFunction("errorBandwidth", "lambda (a,b) -> math.abs((a - b)/a) end");
        // (实际-预测)²
        AviatorEvaluator.defineFunction("differenceSquare", "lambda (a,b) -> math.pow((a - b), 2) end");
        // |实际-预测|
        AviatorEvaluator.defineFunction("differenceAbsolute", "lambda (a,b) -> math.abs(a - b) end");
    }
}
