package org.springblade.flow.engine.custom.handler.condition;

import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FORM_INFO_JSON;

import java.util.List;
import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptException;

import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.Condition;
import org.springblade.flow.base.util.SpringContextHolder;
import org.springblade.flow.engine.assembly.SequenceFlowExPropertyDTO;
import org.springblade.flow.engine.custom.variables.entity.FormDataInfo;
import org.springblade.flow.engine.model.flowengine.shuntjson.childnode.ProperCond;
import org.springblade.flow.engine.model.flowengine.shuntjson.nodejson.ConditionList;
import org.springblade.flow.util.JsonUtil;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import lombok.extern.slf4j.Slf4j;

/**
 * Java8自带的 表达式解析器
 */
@Slf4j
public class NashornCondition implements Condition {
	private static final long serialVersionUID = -5577703954744892854L;
	private String attributeValue = "";

	public NashornCondition(String attributeValue) {
		this.attributeValue = attributeValue;
	}

	public boolean evaluate(String sequenceFlowId, DelegateExecution execution) {
		boolean flag=false;
		ScriptEngine scriptEngine = SpringContextHolder.getBean(ScriptEngine.class);
		FormDataInfo formDataInfo = execution.getVariable(FORM_INFO_JSON, FormDataInfo.class);
		Map<String, Object> map = JsonUtil.stringToMap(formDataInfo.getFormDataJson());
		SequenceFlowExPropertyDTO exPropertyDTO = JSONObject.parseObject(attributeValue, new TypeReference<SequenceFlowExPropertyDTO>() {
		});
		ConditionList conditionNodeList = exPropertyDTO.getConditionNodeList();
		List<ProperCond> conditionList = conditionNodeList.getConditions();
		StringBuilder expression = new StringBuilder();
		for (int i = 0; i < conditionList.size(); i++) {
			String logic = conditionList.get(i).getLogic();
			String field = conditionList.get(i).getField();
			Object form = map.get(field);
			if (form == null) {
				form = "";
			}
			String formValue = stringToAscii(String.valueOf(form));
			String symbol = conditionList.get(i).getSymbol();
			if ("<>".equals(symbol)) {
				symbol = "!=";
			}
			String value = conditionList.get(i).getFiledValue();
			String filedValue = stringToAscii(String.valueOf(value));
			expression.append(formValue + symbol + filedValue);
			if (!StringUtils.isEmpty(logic)) {
				if (i != conditionList.size() - 1) {
					expression.append(" " + logic + " ");
				}
			}
		}
		try {
			String result = String.valueOf(scriptEngine.eval(expression.toString()));
			return Boolean.valueOf(result);
		} catch (ScriptException e) {
			e.printStackTrace();
			StringBuffer message = new StringBuffer("条件脚本解析异常！请联系管理员。");
			message.append("\n节点：" + execution.getCurrentFlowElement().getName() + "——" + execution.getCurrentActivityId());
			message.append("\n异常：" + e.getMessage());
			log.error(message.toString());
		}
		return flag;
	}

	/**
	 * 转成ascii码
	 **/
	private static String stringToAscii(String value) {
		StringBuffer sbu = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			sbu.append((int) chars[i]);
		}
		return sbu.toString();
	}
}
