package org.springblade.flow.engine.custom.xml.impl;


import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.bpmn.converter.CallActivityXMLConverter;
import org.flowable.bpmn.converter.util.BpmnXMLUtil;
import org.flowable.bpmn.model.BaseElement;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.CallActivity;

import lombok.extern.slf4j.Slf4j;

/**
 * @Author:LoveMyOrange
 * @Description: 如果只是取出扩展属性 输出 那么下面代码写法没有问题, 如果 调用完super 还想添加扩展属性,那么表面是正确的,实际上是完全错误
 * 原因: SAX解析机制
 * @Date:Created in 2021/12/17 14:21
 */
@Slf4j
public class CustomCallActivityXMLConverter extends CallActivityXMLConverter {
    @Override
    protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) throws Exception {
        CallActivity callActivity = new CallActivity();
        BpmnXMLUtil.addXMLLocation(callActivity, xtr);
        callActivity.setCalledElement(xtr.getAttributeValue(null, ATTRIBUTE_CALL_ACTIVITY_CALLEDELEMENT));
        callActivity.setCalledElementType(BpmnXMLUtil.getAttributeValue(BpmnXMLConstants.ATTRIBUTE_CALL_ACTIVITY_CALLEDELEMENTTYPE, xtr));
        callActivity.setProcessInstanceName(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_CALL_ACTIVITY_PROCESS_INSTANCE_NAME, xtr));
        callActivity.setBusinessKey(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_BUSINESS_KEY, xtr));
        callActivity.setInheritBusinessKey(Boolean.parseBoolean(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_INHERIT_BUSINESS_KEY, xtr)));
        callActivity.setInheritVariables(Boolean.valueOf(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_CALL_ACTIVITY_INHERITVARIABLES, xtr)));
        callActivity.setSameDeployment(Boolean.valueOf(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_SAME_DEPLOYMENT, xtr)));
        callActivity.setUseLocalScopeForOutParameters(Boolean.valueOf(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_CALL_ACTIVITY_USE_LOCALSCOPE_FOR_OUTPARAMETERS, xtr)));
        callActivity.setCompleteAsync(Boolean.valueOf(BpmnXMLUtil.getAttributeValue(ATTRIBUTE_CALL_ACTIVITY_COMPLETE_ASYNC, xtr)));
        String fallbackToDefaultTenant = BpmnXMLUtil.getAttributeValue(ATTRIBUTE_FALLBACK_TO_DEFAULT_TENANT, xtr);
        if (StringUtils.isNotEmpty(fallbackToDefaultTenant)) {
            callActivity.setFallbackToDefaultTenant(Boolean.valueOf(fallbackToDefaultTenant));
        }

        String idVariableName = BpmnXMLUtil.getAttributeValue(BpmnXMLConstants.ATTRIBUTE_ID_VARIABLE_NAME, xtr);
        if (StringUtils.isNotEmpty(idVariableName)) {
            callActivity.setProcessInstanceIdVariableName(idVariableName);
        }
        BpmnXMLUtil.addCustomAttributes(xtr, callActivity, defaultElementAttributes,defaultActivityAttributes);
        parseChildElements(getXMLElementName(), callActivity, childParserMap, model, xtr);
        return callActivity;
    }

    /**
     * 将扩展属性给添加上去
     * @param element
     * @param model
     * @param xtw
     * @throws Exception
     */
    @Override
    protected void writeAdditionalAttributes(BaseElement element, BpmnModel model, XMLStreamWriter xtw) throws Exception {
        CallActivity callActivity = (CallActivity) element;
        if (StringUtils.isNotEmpty(callActivity.getCalledElement())) {
            xtw.writeAttribute(ATTRIBUTE_CALL_ACTIVITY_CALLEDELEMENT, callActivity.getCalledElement());
        }
        if (StringUtils.isNotEmpty(callActivity.getCalledElementType())) {
            writeQualifiedAttribute(ATTRIBUTE_CALL_ACTIVITY_CALLEDELEMENTTYPE, callActivity.getCalledElementType(), xtw);
        }
        if (StringUtils.isNotEmpty(callActivity.getProcessInstanceName())) {
            writeQualifiedAttribute(ATTRIBUTE_CALL_ACTIVITY_PROCESS_INSTANCE_NAME, callActivity.getProcessInstanceName(), xtw);
        }
        if (StringUtils.isNotEmpty(callActivity.getBusinessKey())) {
            writeQualifiedAttribute(ATTRIBUTE_BUSINESS_KEY, callActivity.getBusinessKey(), xtw);
        }
        if (callActivity.isInheritBusinessKey()) {
            writeQualifiedAttribute(ATTRIBUTE_INHERIT_BUSINESS_KEY, "true", xtw);
        }
        if (callActivity.isUseLocalScopeForOutParameters()) {
            writeQualifiedAttribute(ATTRIBUTE_CALL_ACTIVITY_USE_LOCALSCOPE_FOR_OUTPARAMETERS, "true", xtw);
        }
        if (callActivity.isInheritVariables()) {
            writeQualifiedAttribute(ATTRIBUTE_CALL_ACTIVITY_INHERITVARIABLES, "true", xtw);
        }
        if (callActivity.isSameDeployment()) {
            writeQualifiedAttribute(ATTRIBUTE_SAME_DEPLOYMENT, "true", xtw);
        }
        if (callActivity.isCompleteAsync()) {
            writeQualifiedAttribute(ATTRIBUTE_CALL_ACTIVITY_COMPLETE_ASYNC, "true", xtw);
        }
        if (callActivity.getFallbackToDefaultTenant() != null) {
            writeQualifiedAttribute(ATTRIBUTE_FALLBACK_TO_DEFAULT_TENANT, callActivity.getFallbackToDefaultTenant().toString(), xtw);
        }
        if (callActivity.getProcessInstanceIdVariableName() != null) {
            writeQualifiedAttribute(ATTRIBUTE_ID_VARIABLE_NAME, callActivity.getProcessInstanceIdVariableName(), xtw);
        }

        // write custom attributes
        BpmnXMLUtil.writeCustomAttributes(callActivity.getAttributes().values(), xtw, defaultElementAttributes,
                defaultActivityAttributes);

    }
}
