package cn.ibizlab.core.data.lite;

import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.Inflector;
import com.alibaba.fastjson.JSON;
import net.ibizsys.model.IPSSystem;
import net.ibizsys.model.PSModelServiceImpl;
import net.ibizsys.model.database.IPSDEFDTColumn;
import net.ibizsys.model.database.IPSSysDBTable;
import net.ibizsys.model.dataentity.IPSDataEntity;
import net.ibizsys.model.dataentity.defield.IPSDEField;
import net.ibizsys.model.dataentity.defield.IPSLinkDEField;
import net.ibizsys.model.dataentity.der.IPSDER1N;
import net.ibizsys.model.dataentity.der.IPSDERBase;
import net.ibizsys.model.dataentity.ds.IPSDEDataQueryCode;
import net.ibizsys.model.dataentity.ds.IPSDEDataQueryCodeCond;
import net.ibizsys.model.dataentity.ds.IPSDEDataSetGroupParam;
import net.ibizsys.model.dataentity.ds.PSDEDataSetGroupParamImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class DynamicModelService {


    public String getModelPath()
    {
        return LiteStorage.MODEL_PATH;
    }

    private Map<String, IPSSystem> dynamicSystems;
    public Object systemLock = new Object();

    public  synchronized IPSSystem getDynamicSystem(String system)
    {
        synchronized(systemLock)
        {
            if(dynamicSystems==null)
                dynamicSystems=new HashMap<>();
            if(dynamicSystems.containsKey(system))
                return dynamicSystems.get(system);
        }

        return initDynamicSystem(system);
    }

    private IPSSystem initDynamicSystem(String system)
    {
        if(dynamicSystems==null)
            dynamicSystems=new HashMap<>();

        IPSSystem iPSSystem = null;
        String strPSModelFolderPath=null;
        if(Files.exists(Paths.get(getModelPath(),system,"model","PSSYSTEM.json"))) {
            strPSModelFolderPath=Paths.get(getModelPath(),system,"model").toString();
        }
        else
        {
            Map<String,DstSystemModel> allDynamicModel=getProxy().findAllDynamicModel();
            if(allDynamicModel.containsKey(system))
                strPSModelFolderPath = allDynamicModel.get(system).getDynamicModelPath();
        }
        if(StringUtils.isEmpty(strPSModelFolderPath))
            throw new BadRequestAlertException("加载系统模型错误,未找到对应模型目录", "DynamicSystem", system);

        PSModelServiceImpl psModelService = new PSModelServiceImpl();
        psModelService.setPSModelFolderPath(strPSModelFolderPath);
        try {
            iPSSystem = psModelService.getPSSystem();
            if (iPSSystem == null)
                throw new BadRequestAlertException("加载系统模型错误", "DynamicSystem", system);
            dynamicSystems.put(system, iPSSystem);
            if (!system.equals(iPSSystem.getCodeName()))
                dynamicSystems.put(iPSSystem.getCodeName(), iPSSystem);
            if (!iPSSystem.getCodeName().toLowerCase().equals(iPSSystem.getCodeName()))
                dynamicSystems.put(iPSSystem.getCodeName().toLowerCase(), iPSSystem);

        } catch (Exception e) {
            throw new BadRequestAlertException(String.format("加载系统模型错误:%s", e.getMessage()), "DynamicSystem", system);
        }
        return iPSSystem;
    }

    @Cacheable( value="syspssystem",key = "'row:sys-dst-sys-dynamic'")
    public Map<String,DstSystemModel> findAllDynamicModel()
    {
        Map<String,DstSystemModel> models=new HashMap<>();
        loopModelDir(new File(getModelPath()),models);
        return models;
    }

    private void loopModelDir(File dir,Map<String,DstSystemModel> models)
    {
        if(dir.isDirectory())
        {
            Path path=Paths.get(dir.getAbsolutePath(),"PSSYSTEM.json");
            File check=path.toFile();
            if(check.exists())
            {
                DstSystemModel dstSystemModel=new DstSystemModel().fromPath(path);
                if(dstSystemModel!=null&&(!StringUtils.isEmpty(dstSystemModel.getPssystemid())))
                {
                    String system=dstSystemModel.getPssystemid();
                    if(models.containsKey(system)&&models.get(system).getLastModify()>=dstSystemModel.getLastModify())
                        return;

                    models.put(system, dstSystemModel);
                    if (!system.toLowerCase().equals(system))
                        models.put(system.toLowerCase(), dstSystemModel);

                    String deployId=path.getParent().getFileName().toString();
                    if("model".equalsIgnoreCase(deployId))
                        deployId=dir.getParentFile().getName();
                    if(!system.equalsIgnoreCase(deployId))
                    {
                        models.put(deployId, dstSystemModel);
                        if (!deployId.toLowerCase().equals(deployId))
                            models.put(deployId.toLowerCase(), dstSystemModel);
                    }
                }
                return;
            }
            else
            {
                for(File sub:dir.listFiles())
                {
                    loopModelDir(sub,models);
                }
            }
        }
    }

    @Cacheable( value="meta-entities", key = "'system:'+#p0")
    public Map<String,MetaEntityModel> getEntities(String system) throws Exception
    {
        Map<String,MetaEntityModel> entities=new HashMap<>();
        IPSSystem iPSSystem=getProxy().getDynamicSystem(system);
        int i=1;
        for(IPSDataEntity dataEntity:iPSSystem.getAllPSDataEntities()){
            MetaEntityModel metaEntityModel=new MetaEntityModel();
            metaEntityModel.setEntityId(dataEntity.getId()).setEntityName(dataEntity.getName())
                    .setLogicName(dataEntity.getLogicName()).setCodeName(dataEntity.getCodeName()).setTableName(dataEntity.getTableName())
                    .setDsId(iPSSystem.getCodeName()+"-"+((StringUtils.isEmpty(dataEntity.getDSLink())||dataEntity.getDSLink().equalsIgnoreCase("DEFAULT"))?"master":dataEntity.getDSLink()))
                    .setDsName(metaEntityModel.getDsId())
                    .setSystemId(iPSSystem.getCodeName()).setSystemName(iPSSystem.getLogicName()).setShowOrder(i);
            i++;
            entities.put(metaEntityModel.getCodeName(),metaEntityModel);
            if(!metaEntityModel.getCodeName().toLowerCase().equals(metaEntityModel.getCodeName()))
                entities.put(metaEntityModel.getCodeName().toLowerCase(),metaEntityModel);
            if(!entities.containsKey(metaEntityModel.getEntityName())) {
                entities.put(metaEntityModel.getEntityName(), metaEntityModel);
            }
            if(!entities.containsKey(metaEntityModel.getEntityName().toLowerCase())) {
                entities.put(metaEntityModel.getEntityName().toLowerCase(), metaEntityModel);
            }
            String pluralize=Inflector.getInstance().pluralize(metaEntityModel.getCodeName()).toLowerCase();
            if(!entities.containsKey(pluralize)) {
                entities.put(pluralize, metaEntityModel);
            }

        }
        return entities;
    }


    public  EntityModel getDynamicEntity(String system,String entity) throws Exception
    {
        MetaEntityModel metaEntityModel=getProxy().getEntities(system).get(entity);
        if(metaEntityModel==null)
            throw new BadRequestAlertException("未找到对应的实体模型","DynamicEntity",entity);
        IPSSystem iPSSystem=getProxy().getDynamicSystem(system);
        IPSDataEntity dataEntity = iPSSystem.getPSDataEntity(metaEntityModel.getEntityId(),true);
        if(dataEntity==null)
            throw new BadRequestAlertException("未找到对应的实体模型","DynamicEntity",entity);
        EntityModel entityModel=new EntityModel();

        if(dataEntity.isLogicValid())
        {
            List<Setting> settingList=new ArrayList<>();
            String val=dataEntity.getValidLogicValue();
            if(StringUtils.isEmpty(val))val="1";
            String deVal=dataEntity.getInvalidLogicValue();
            if(StringUtils.isEmpty(deVal))deVal="0";
            settingList.add(new Setting().setProperty("logicval").setValue(val));
            settingList.add(new Setting().setProperty("logicdelval").setValue(deVal));
            metaEntityModel.setExtParams(JSON.toJSONString(settingList));
        }
        entityModel.setEntity(metaEntityModel);

        List<String> dsTypes=new ArrayList<>();

        if(dataEntity.getAllPSDEDBConfigs()!=null)
        {
            dataEntity.getAllPSDEDBConfigs().forEach(item->{
                dsTypes.add(item.getDBType().toLowerCase().replace("mysql5","mysql"));
                if(!entityModel.getTableName().equalsIgnoreCase(item.getTableName()))
                    entityModel.getEntity().set("table-"+item.getDBType().toLowerCase().replace("mysql5","mysql"),item.getTableName());
            });
        }

        if(dsTypes.size()>0)
            entityModel.getEntity().set("ds_types",String.join(",",dsTypes));

        Map<String,FieldModel> fieldMaps=new LinkedHashMap<>();
        for(IPSDEField defield:dataEntity.getAllPSDEFields())
        {

            FieldModel fieldModel=new FieldModel();
            MetaFieldModel metaFieldModel=new MetaFieldModel();
            metaFieldModel.setFieldId(defield.getId()).setFieldName(defield.getName()).setCodeName(defield.getCodeName()).setFieldLogicName(defield.getLogicName())
                    .setEntityId(dataEntity.getId()).setEntityCodeName(dataEntity.getCodeName()).setEntityName(dataEntity.getName()).setSystemId(metaEntityModel.getSystemId())
                    .setFieldUniName(dataEntity.getName()+"."+defield.getName()).setFieldShowName(String.format("%1$s-%2$s[%3$s]",defield.getName(),defield.getLogicName(),dataEntity.getName()))
                    .setKeyField(defield.isKeyDEField()?1:null).setMajorField(defield.isMajorDEField()?1:null).setUnionKey(defield.getUnionKeyValue()).setFieldType(defield.getDataType())
            .setPredefined(defield.getPredefinedType()).setDict(defield.getPSCodeList()!=null?defield.getPSCodeList().getCodeName():null).setNullable(defield.isAllowEmpty()?1:0)
            .setPhysicalField(defield.isPhisicalDEField()?1:0).setDataType(DataType.findTypeName(defield.getStdDataType())).setDataLength(defield.getLength()).setDataPreci(defield.getPrecision())
            .setIsEnableAudit(defield.isEnableAudit()?1:null).setShowOrder(defield.getImportOrder());

            if(defield.getAllPSDEFDTColumns()!=null)
            {
                defield.getAllPSDEFDTColumns().forEach(col->{
                    if(!metaFieldModel.getFieldName().equalsIgnoreCase(col.getColumnName()))
                        metaFieldModel.set("column-"+col.getDBType().toLowerCase().replace("mysql5","mysql"),col.getColumnName());
                    if(StringUtils.isEmpty(metaFieldModel)&&defield.isFormulaDEField()&&(!StringUtils.isEmpty(col.getQueryCodeExp())))
                        metaFieldModel.setExpression(col.getQueryCodeExp().replace("`","").replace("[","").replace("]",""));
                });
            }

            if(defield.isLinkDEField() && defield instanceof IPSLinkDEField)
            {
                IPSLinkDEField linkDEField = (IPSLinkDEField)defield;
                metaFieldModel.setRefFieldId(linkDEField.getRelatedPSDEField().getId())
                .setRefFieldName(linkDEField.getRelatedPSDEField().getName()).setRelationId(linkDEField.getPSDER().getId())
                .setRelationName(linkDEField.getPSDER().getName()).setRelationCodeName(linkDEField.getPSDER().getCodeName()).setRefEntityName(linkDEField.getPSDER().getMajorPSDataEntity().getName());
            }

            if(!ObjectUtils.isEmpty(defield.getAllPSDEFSearchModes()))
            {
                List<String> modes=new ArrayList<>();
                defield.getAllPSDEFSearchModes().forEach(item->modes.add(item.getValueOP().toLowerCase()));
                if(defield.isEnableQuickSearch())
                    modes.add("query");
                metaFieldModel.set("search_modes",String.join(",",modes));
            }

            fieldModel.setCodeName(metaFieldModel.getCodeName()).setColumnName(metaFieldModel.getFieldName()).setUnionName(metaFieldModel.getFieldUniName()).setShowName(metaFieldModel.getFieldShowName())
            .setComment(metaFieldModel.getFieldLogicName()).setField(metaFieldModel);

            fieldMaps.put(fieldModel.getColumnName(),fieldModel);
            entityModel.addField(fieldModel);
        }

        if(dataEntity.getMinorPSDERs()!=null)
        {
            for(IPSDERBase der : dataEntity.getMinorPSDERs())
            {
                RelationshipModel rel=new RelationshipModel();
                rel.setCodeName(der.getCodeName()).setEntityId(der.getMajorPSDataEntity().getId())
                        .setEntityCodeName(der.getMajorPSDataEntity().getCodeName()).setEntityName(der.getMajorPSDataEntity().getName())
                        .setEntityLogicName(der.getMajorPSDataEntity().getLogicName()).setSystemId(iPSSystem.getCodeName()).setTableName(der.getMajorPSDataEntity().getTableName());

                MetaRelationshipModel metaRel=new MetaRelationshipModel();
                metaRel.setId(der.getId()).setName(der.getName()).setRelationType(der.getDERType()).setCodeName(der.getCodeName()).setRefEntityId(der.getMajorPSDataEntity().getId())
                        .setRefEntityName(der.getMajorPSDataEntity().getName()).setEntityId(dataEntity.getId()).setEntityName(dataEntity.getName()).setNestedName(der.getMinorCodeName())
                        .setSystemId(iPSSystem.getCodeName());

                if(der instanceof IPSDER1N)
                {
                    IPSDER1N der1n=(IPSDER1N)der;
                    MetaLookupModel lookupModel=new MetaLookupModel().setRelationid(der.getId())
                            .setFieldname(der1n.getPickupDEFName()).setReffieldname(der1n.getPSPickupDEField().getRelatedPSDEField().getName());
                    metaRel.addLookup(lookupModel);
                }

                rel.setRelation(metaRel);
                entityModel.addReference(rel);
            }

        }

        if(dataEntity.getMajorPSDERs()!=null)
        {
            for(IPSDERBase der : dataEntity.getMajorPSDERs())
            {
                if(StringUtils.isEmpty(der.getMinorCodeName()))
                    continue;
                RelationshipModel rel=new RelationshipModel();
                rel.setCodeName(der.getMinorCodeName()).setEntityId(der.getMinorPSDataEntity().getId())
                        .setEntityCodeName(der.getMinorPSDataEntity().getCodeName()).setEntityName(der.getMinorPSDataEntity().getName())
                        .setEntityLogicName(der.getMinorPSDataEntity().getLogicName()).setSystemId(iPSSystem.getCodeName()).setTableName(der.getMinorPSDataEntity().getTableName());

                MetaRelationshipModel metaRel=new MetaRelationshipModel();
                metaRel.setId(der.getId()).setName(der.getName()).setRelationType(der.getDERType()).setCodeName(der.getCodeName()).setRefEntityId(der.getMajorPSDataEntity().getId())
                        .setRefEntityName(der.getMajorPSDataEntity().getName()).setEntityId(dataEntity.getId()).setEntityName(dataEntity.getName()).setNestedName(der.getMinorCodeName())
                        .setSystemId(iPSSystem.getCodeName());

                if(der instanceof IPSDER1N)
                {
                    IPSDER1N der1n=(IPSDER1N)der;
                    MetaLookupModel lookupModel=new MetaLookupModel().setRelationid(der.getId())
                            .setFieldname(der1n.getPickupDEFName()).setReffieldname(der1n.getPSPickupDEField().getRelatedPSDEField().getName());
                    metaRel.addLookup(lookupModel);
                }

                rel.setRelation(metaRel);
                entityModel.addNested(rel);
            }
        }

        if(dataEntity.getAllPSDEDataQueries()!=null)
        {
            dataEntity.getAllPSDEDataQueries().forEach(dataQuery->{

                try {
                    if(dataQuery.getAllPSDEDataQueryCodes()!=null)
                    {
                        dataQuery.getAllPSDEDataQueryCodes().forEach(dq->{

                            String code=getQueryCode(dq);

                            MetaDataSetModel dsModel=new MetaDataSetModel().setDatasetId(entityModel.getEntityName().toLowerCase()+"-dq-"+dataQuery.getCodeName()+"-"+dq.getDBType().toLowerCase().replace("mysql5","mysql"))
                                    .setDatasetName(dataQuery.getLogicName()).setCodeName(dataQuery.getCodeName())
                                    .setEntityId(entityModel.getEntityId()).setEntityName(entityModel.getEntityName()).setDsCode(code);
                            entityModel.addDataSet(dsModel);
                        });
                    }
                } catch (Exception exception) {

                }

            });
        }

        if(dataEntity.getAllPSDEDataSets()!=null)
        {
            dataEntity.getAllPSDEDataSets().forEach(dataSet->{


                try {

                    if(dataSet.getPSDEDataQueries()!=null)
                    {



                        Map<String,String> map =new HashMap<>();
                        dataSet.getPSDEDataQueries().forEach(dataQuery->{

                            try {
                                if(dataQuery.getAllPSDEDataQueryCodes()!=null)
                                {
                                    dataQuery.getAllPSDEDataQueryCodes().forEach(dq->{
                                        String code="";
                                        if(!map.containsKey(dq.getDBType())) {
                                            map.put(dq.getDBType(), "");
                                            code="";
                                        }
                                        else {
                                            code = map.get(dq.getDBType());
                                            code = code+"\r\n union all \r\n";
                                        }
                                        code = code+ getQueryCode(dq);
                                        ;//"<include refid=\""+entityModel.getEntityName().toLowerCase()+"_dq_"+dataQuery.getCodeName()+"_"+dq.getDBType().toLowerCase()+"\"/>";
                                        map.put(dq.getDBType(),"select t1.* from ("+code+") t1");
                                    });
                                }
                            } catch (Exception exception) {

                            }

                        });

                        for(Map.Entry<String,String> entry:map.entrySet())
                        {
                            String sql=null;

                            if(dataSet.getGroupMode()==1||dataSet.getMajorSortPSDEField()!=null)
                            {

                                if(dataSet.getGroupMode()==1&&(!ObjectUtils.isEmpty(dataSet.getPSDEDataSetGroupParams())))
                                {
                                    sql="select ";
                                    int i=0;
                                    for(IPSDEDataSetGroupParam obj:dataSet.getPSDEDataSetGroupParams())
                                    {
                                        if(!(obj instanceof PSDEDataSetGroupParamImpl))
                                            continue;
                                        PSDEDataSetGroupParamImpl groupParam=(PSDEDataSetGroupParamImpl)obj;
                                        if(i>0)sql=sql.concat(",");
                                        if(groupParam.isEnableGroup())
                                        {
                                            if(!StringUtils.isEmpty(groupParam.getGroupCode()))
                                                sql=sql.concat(groupParam.getGroupCode());
                                            else
                                                sql=sql.concat(groupParam.getName());
                                        }
                                        else
                                            sql=sql.concat(groupParam.getGroupCode());
                                        sql=sql.concat(" as ").concat(groupParam.getName().toLowerCase());
                                        i++;
                                    }
                                    sql=sql.concat(" from  ( %s ) t1");
                                }
                                else
                                    sql="select t1.* from ( %s ) t1";


                                if(dataSet.getGroupMode()==1&&(!ObjectUtils.isEmpty(dataSet.getPSDEDataSetGroupParams())))
                                {
                                    sql=sql.concat(" group by ");
                                    int i=0;
                                    for(IPSDEDataSetGroupParam obj:dataSet.getPSDEDataSetGroupParams())
                                    {
                                        if(!(obj instanceof PSDEDataSetGroupParamImpl))
                                            continue;
                                        PSDEDataSetGroupParamImpl groupParam=(PSDEDataSetGroupParamImpl)obj;
                                        if(groupParam.isEnableGroup())
                                        {
                                            if(i>0)sql=sql.concat(",");

                                            if(!StringUtils.isEmpty(groupParam.getGroupCode()))
                                                sql=sql.concat(groupParam.getGroupCode());
                                            else
                                                sql=sql.concat(groupParam.getName());
                                            i++;
                                        }
                                    }
                                }

                                if(dataSet.getMajorSortPSDEField()!=null)
                                {
                                    IPSDEFDTColumn column = dataSet.getMajorSortPSDEField().getPSDEFDTColumn(entry.getKey().toLowerCase().replace("mysql5","mysql"),false);

                                    sql=sql.concat(" order by ").concat(column==null?dataSet.getMajorSortPSDEField().getName():column.getColumnName());
                                    if(!StringUtils.isEmpty(dataSet.getMajorSortDir()))
                                        sql=sql.concat(" ").concat(dataSet.getMajorSortDir());
                                    if(dataSet.getMinorSortPSDEField()!=null)
                                    {
                                        IPSDEFDTColumn subCol = dataSet.getMinorSortPSDEField().getPSDEFDTColumn(entry.getKey().toLowerCase().replace("mysql5","mysql"),false);

                                        sql=sql.concat(",").concat(subCol==null?dataSet.getMinorSortPSDEField().getName():subCol.getColumnName());
                                        if(!StringUtils.isEmpty(dataSet.getMinorSortDir()))
                                            sql=sql.concat(" ").concat(dataSet.getMinorSortDir());

                                    }
                                }
                            }
                            MetaDataSetModel dsModel=new MetaDataSetModel().setDatasetId(entityModel.getEntityName().toLowerCase()+"-ds-"+dataSet.getCodeName()+"-"+entry.getKey().toLowerCase().replace("mysql5","mysql"))
                                    .setDatasetName(dataSet.getLogicName()).setCodeName(dataSet.getCodeName())
                                    .setEntityId(entityModel.getEntityId()).setEntityName(entityModel.getEntityName()).setDsCode(entry.getValue().toLowerCase().replace("mysql5","mysql")).setDsModel(sql);
                            entityModel.addDataSet(dsModel);
                        }

                    }
                } catch (Exception exception) {

                }

            });


        }


        return entityModel;
    }

    @Autowired
    @Lazy
    private DynamicModelService proxy;

    public DynamicModelService getProxy()
    {
        return proxy;
    }



    public static enum  DataType {
        UNKNOWN(0,"UNKNOWN"),
        BIGINT(1,"BIGINT"),
        BINARY(2,"BINARY"),
        BIT(3,"BIT"),
        CHAR(4,"CHAR"),
        DATETIME(5,"DATETIME"),
        DECIMAL(6,"DECIMAL"),
        FLOAT(7,"FLOAT"),
        IMAGE(8,"IMAGE"),
        INT(9,"INT"),
        MONEY(10,"MONEY"),
        NCHAR(11,"NCHAR"),
        NTEXT(12,"NTEXT"),
        NVARCHAR(13,"NVARCHAR"),
        NUMERIC(14,"NUMERIC"),
        REAL(15,"REAL"),
        SMALLDATETIME(16,"SMALLDATETIME"),
        SMALLINT(17,"SMALLINT"),
        SMALLMONEY(18,"SMALLMONEY"),
        SQL_VARIANT(19,"SQL_VARIANT"),
        SYSNAME(20,"SYSNAME"),
        TEXT(21,"TEXT"),
        TIMESTAMP(22,"TIMESTAMP"),
        TINYINT(23,"TINYINT"),
        VARBINARY(24,"VARBINARY"),
        VARCHAR(25,"VARCHAR"),
        UNIQUEIDENTIFIER(26,"UNIQUEIDENTIFIER"),
        DATE(27,"DATE"),
        TIME(28,"TIME");

        public final int code;
        public final String name;

        private DataType(int code, String name) {
            this.code = code;
            this.name = name;
        }

        public int getCode() {
            return code;
        }

        public String getName() {
            return name;
        }

        public static String findTypeName(Integer type) {
            for (DataType userTypeEnum : DataType.values()) {
                if (userTypeEnum.getCode()==type) {
                    return userTypeEnum.getName();
                }
            }
            return VARCHAR.getName();
        }

    }


    private String contextParamConvert(String contextParam)
    {
        String resultParam=getJavaSqlCode(contextParam).replaceAll("(IN|in) \\(\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)}\\)","$1 (\\${srf.$2.$3})");
        resultParam=resultParam.replaceAll("\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)}","#{srf.$1.$2}");
        resultParam=resultParam.replaceAll("\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)'\\)}","#{srf.$1.$2}");

        Pattern p = Pattern.compile("srf.(datacontext|sessioncontext|webcontext).(\\w+)");
        Matcher m = p.matcher(resultParam);
        StringBuffer sb = new StringBuffer();

        while(m.find()){
            String match = m.group();

            resultParam=resultParam.replace(match,match.toLowerCase());

        }

        resultParam=resultParam.replace("AND t11.SRFDCID = '__SRFSAASDCID__'","");
        return resultParam;
    }


    private String getQueryCode(IPSDEDataQueryCode dq)
    {
        String code=contextParamConvert(dq.getQueryCode());
        if(dq.getPSDEDataQueryCodeConds()!=null)
        {
            int i=0;
            boolean b=checkIgnoreNullvalueCond(dq.getPSDEDataQueryCodeConds());
            for(IPSDEDataQueryCodeCond cond:dq.getPSDEDataQueryCodeConds())
            {
                if(i==0)
                    code=code.concat(" where ");
                else if(i>0)
                    code=code.concat(" and ");

                code=code.concat(b?checkNullContextParamConvert(cond.getCustomCond()):contextParamConvert(cond.getCustomCond()));
                i++;
            }
        }
        return code;
    }



    private String getJavaSqlCode(String strSQLCode)
    {
        strSQLCode = strSQLCode.replace("\r\n", " ");
        strSQLCode = strSQLCode.replace("\r", " ");
        strSQLCode = strSQLCode.replace("\n", " ");
        strSQLCode = strSQLCode.replace("\"", "\\\"");
        return strSQLCode;
    }


    private String checkNullContextParamConvert(String contextParam) {
        String resultParam = getJavaSqlCode(contextParam).replaceAll("<#assign _value=srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)><#if _value\\?length gt 0>(.*?)\\(\\$\\{_value}\\)<#else>1=1</#if>"," ('${srf.$1.$2}'=null or '${srf.$1.$2}'='' or  $4  \\${srf.$1.$2} ");
        resultParam = resultParam.replaceAll("<#assign _value=srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)><#if _value\\?length gt 0>(.*?)\\$\\{_value}(.*?)?<#else>1=1</#if>", " (#{srf.$1.$2}=null or #{srf.$1.$2}='' or $4#{srf.$1.$2}$5)");
        resultParam=contextParamConvert(resultParam);
        return resultParam;
    }

    private boolean checkIgnoreNullvalueCond(List<IPSDEDataQueryCodeCond> list)
    {
        if(list!=null)
        {
            for(IPSDEDataQueryCodeCond cond:list)
            {
                if(getJavaSqlCode(cond.getCustomCond()).matches("(.*?)srf(datacontext|sessioncontext|webcontext)(.*?)\\\\\"ignoreempty\\\\\":true(.*?)"))
                    return true;
            }
        }
        return false;
    }


}
