package com.sagacloud.endpoints;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sagacloud.broadcast.MessageHandler;
import com.sagacloud.cache.utils.CacheUtil;
import com.sagacloud.dict.EqStaticInfo;
import com.sagacloud.dict.InfosUtil;
import com.sagacloud.utils.CommonMethods;
import com.sagacloud.utils.CommonUtil;
import com.sagacloud.utils.Const;
import com.sagacloud.utils.DpUtils;
import com.sagacloud.utils.InfoCodeUtil;
import com.sagacloud.utils.JSONCheckUtil;
import com.sagacloud.utils.ObjectUtil;
import com.sagacloud.utils.PropertyUtil;
import com.sagacloud.utils.jsonHelper.infoPoint.InfoPoint;
import com.sagacloud.utils.objectLog.ActivityLogObject;
import com.sagacloud.utils.objectLog.ActivityLogRunnable;
import com.sagacloud.utils.objectLog.ActivityLogUtil;
import com.sagacloud.utils.objects.CommonQueryCriteria;
import com.sagacloud.utils.objects.ObjectIdName;
import com.sagacloud.utils.objects.ObjectType;
import com.sagacloud.utils.qrCode.QRCodeRunnable;
import com.sagacloud.utils.relationUtils.PropertyRelUtil;
import com.sagacloud.utils.relationUtils.RelationBuilder;
import com.sagacloud.utils.relationUtils.SubsetUtil;
import com.sagacloud.utils.tables.ObjectTable;



/**
 * Created by wushengzong on 2017/4/19.
 */
@Path("equipment")
public class Equipment {
    private static final Logger log = LoggerFactory.getLogger(Equipment.class);

    @Path("/batch/create_update")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String batchUpdate(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr){
    	final String repeat_id = "repeat_id";
    	
        JSONObject postParam = JSONObject.parseObject(jsonStr);
        JSONObject postBody = JSONObject.parseObject(jsonStr);
        // 先批量插入
        String insertBatchResult = batchCreate(projectId, postParam);
        
        JSONObject insetResultBody = JSONObject.parseObject(insertBatchResult);
        JSONArray errorAray = insetResultBody.getJSONArray("Error");
        if(null != errorAray) {
        	insetResultBody.put("error_insert", errorAray);
        	insetResultBody.remove("Error");
        }
        
        // 含有已存在的对象，进行更新操作
        if(insertBatchResult.contains(repeat_id)) {
        	// 已存在对象的id集合
        	Set<String> repeatIdSet = new HashSet<>();
        	JSONArray errorNewAray = new JSONArray();
        	if(null != errorAray) {
        		for(int i=0; i<errorAray.size(); i++) {
        			if(null != errorAray.getJSONObject(i) && null != errorAray.getJSONObject(i).getString(repeat_id)) {
        				repeatIdSet.add(errorAray.getJSONObject(i).getString(repeat_id));
        			}else {
        				errorNewAray.add(errorAray.getJSONObject(i));
        			}
        		}
         	}
        	
        	if(!errorNewAray.isEmpty()) {
        		insetResultBody.put("error_insert", errorNewAray);
        	}else {
        		insetResultBody.remove("error_insert");
        		insetResultBody.put("Result", "success");
        	}
        	
        	
        	if(!repeatIdSet.isEmpty()) {
        		insertBatchResult = ObjectUtil.insertParamToExcuteUpdate(projectId, postBody, insetResultBody, repeatIdSet);
        	}
        }
        
        return insertBatchResult;
    }

    @Path("/batch/create")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String batchCreate(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr){
        JSONObject postBody = JSONObject.parseObject(jsonStr);
        return batchCreate(projectId, postBody);
    }

    /**生成对象id和各位置对象关系
     * @param pjId
     * @param buildingMap
     * @param floorMap
     * @param equipMap
     * @param criterias
     * @param errors
     */
    private void countEquipRelation(String pjId, Map<String, Set<String>> buildingMap, Map<String, String> floorMap, Map<String, String> equipMap, JSONArray criterias, JSONArray errors) {
        for(int i = criterias.size() - 1; i > -1; --i){
            JSONObject singleObj = criterias.getJSONObject(i);
            String id = singleObj.getString("id");
            String floorId = singleObj.getString("floor_id");
            String buildId = singleObj.getString("building_id");
            String equipId = singleObj.getString("equip_id");
            if(floorId!= null && DpUtils.checkId(pjId, floorId)){
                floorMap.put(id, floorId);
            }
            if(buildId!= null && DpUtils.checkId(pjId, buildId)){
                if(buildingMap.get(id) == null){
                    buildingMap.put(id, new HashSet<>());
                }
                buildingMap.get(id).add(buildId);
            }
            if(id.startsWith("Sy")){  //系统可以属于多个建筑
                JSONArray syArr = singleObj.getJSONArray("building_ids");
                if(syArr != null){
                    if(buildingMap.get(id) == null){
                        buildingMap.put(id, new HashSet<>());
                    }
                    for (int j = 0; j < syArr.size(); j++) {
                        String bId = syArr.getString(j);
                        if(DpUtils.checkId(pjId, bId)){
                            buildingMap.get(id).add(bId);
                        }

                    }
                }
            }
            if(equipMap != null && DpUtils.checkId(pjId, equipId)){
                equipMap.put(id, equipId);
            }
        }
    }

    public String batchCreate(@QueryParam(Const.PROJECT_ID) String projectId, JSONObject postBody){
        try {
            String imageUrl = postBody.getString("innerImageUrl");
            Boolean genPersagyQr = postBody.getBoolean("genPersagyQr");
            if(genPersagyQr == null){
                genPersagyQr = false;
            }
            JSONArray criterias = postBody.getJSONArray("criterias");
            if(criterias == null || criterias.size() == 0){
                return DpUtils.returnJSONArray(new JSONArray(), "");
            }
            JSONArray errors = new JSONArray();
            String pjId = projectId.substring(2);
//            一. 准备数据
//            1. 为每个对象生成id, 或者检验指定的id符不符合规则, 检验是否有重复指定的id.
//            2. 统计  设备/系统/部件 类型, 获取每个类型下的信息点列表. (剔除错误类型)
            Set<String> typeSet = JSONCheckUtil.checkEqSyEcGenerateId(pjId, criterias, errors, "equipment_category");
            HashMap<String, HashMap<String, InfoPoint>> infoCodeMap = InfoCodeUtil.getWholeInfosWithCustomMap(pjId, typeSet.toArray(new String[0]));
//            3. 通过2获取到的信息点列表, 验证信息点的key是否正确(剔除错误)
//            4. 验证信息点节点的格式是否正确.
            JSONCheckUtil.verifyEqInfos(projectId, criterias, infoCodeMap, "equipment_category", errors);
//            5. 统计  building_id, floor_id(仅设备允许), (跳过关系id错误的关系).
            Map<String, Set<String>> buildingMap = new HashMap<>();  // id --> building_id
            Map<String, String> floorMap = new HashMap<>();     // id --> floor_id
            countEquipRelation(pjId, buildingMap, floorMap, null, criterias, errors); // 填充上面两个Map
//            6. 查看是否有二维码信息点EquipQRCode, 有的话不再插入二维码, 没有的话, 添加二维码信息点, 同时记录id(用于接口返回后添加二维码图片).
            Map<String, String> idFileKeyMap = new HashMap<>();
            JSONCheckUtil.addQRCodeInfo(projectId, criterias, "EquipQRCode", idFileKeyMap);
//            二. 插入数据
//            1. 插入对象表 (将失败的剔除)
            if(criterias.size() == 0)
                return PropertyUtil.returnOnCreation(criterias, errors, "");
            String time = CommonUtil.getTime();
            DpUtils.submitToObjectTable(pjId, criterias, time, errors);
            // 补充信息点数据
            ArrayList<ActivityLogObject> logList = new ArrayList<>();
            for(int i = 0; i < criterias.size(); ++i) {
                JSONObject single = criterias.getJSONObject(i);
                String id = single.getString("id");
                ObjectType ot = id.startsWith("Eq")?ObjectType.equipment : ObjectType.system;
                String detailedType = single.getString("equipment_category");
                InfosUtil.addIdName(pjId, ot, detailedType, single.getJSONObject("infos"), id, new ObjectIdName());
                // 添加要发送到activeMQ的消息
                ActivityLogUtil.addMessageToQueue(pjId, time, logList, id, ot);
            }
            JSONArray success = new JSONArray();
            PropertyUtil.putIDToInfos(criterias, success);

//            2. 插入关系 (失败的话, 提示 关系插入失败, 不剔除)
            RelationBuilder relationBuilder = new RelationBuilder(pjId);
            relationBuilder.addTo2From2(buildingMap, "Subset", "3");
            relationBuilder.addFrom2To(floorMap, "EquipinFloor", "1");
            boolean hasException = false;
            try {
                relationBuilder.filterInvalidObjects().fillGraphId().insert();
            }catch (Exception ignore){hasException = true;}
            Map<String, Set<String>> failureRelationMap = null;
            if(hasException) {
                failureRelationMap = relationBuilder.getErrorMap(relationBuilder.getData(), relationBuilder.getError(), "Sy", "Eq");
            }else{
                failureRelationMap = relationBuilder.getErrorMap(null, relationBuilder.getError(), "Sy", "Eq");
            }
            JSONCheckUtil.remindErrorRelation(failureRelationMap, success);
//            3. 插入信息点
            ObjectUtil.batchUpdate(pjId, criterias, false, true, false, new CommonQueryCriteria());
//            三. 接口返回后
//            1. 发送activeMQ消息, 记录日志
            ActivityLogRunnable activityLog = new ActivityLogRunnable(logList);
            ActivityLogUtil.pool.submit(activityLog);
//            2. 生成二维码文件, 上传到文件服务器
            QRCodeRunnable qrCodeRunnable = new QRCodeRunnable(idFileKeyMap, imageUrl, projectId, genPersagyQr);
            ActivityLogUtil.pool.submit(qrCodeRunnable);
            return PropertyUtil.returnOnCreation(success, errors, "");
        }catch (Exception ex)
        {
            ex.printStackTrace();
            return DpUtils.errorJsonMsg(ex.getMessage() == null? "添加失败!": ex.getMessage());
        }
    }
    @Path("/create")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String create(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr){
        JSONObject postObj = JSONObject.parseObject(jsonStr);
        JSONObject postBody = new JSONObject();
        JSONArray criterias = new JSONArray();
        criterias.add(postObj);
        postBody.put("criterias", criterias);
        String result = batchCreate(projectId, postBody);
        JSONObject criteria = JSONObject.parseObject(result);
        return DpUtils.batchToSingle(criteria);
    }



    // 老接口， 不会自动添加二维码
//    @Path("/create")
//    @POST
//    @Produces(MediaType.APPLICATION_JSON)
//    public String create(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr){
//        try {
//            JSONObject insertJson = JSONObject.parseObject(jsonStr);
//            if(insertJson.get("equipment_category") == null || insertJson.get(Const.JSON_FIELD_JSON_DATA_INFOS) == null){
//                return DpUtils.errorJsonMsg("缺少必要字段");
//            }
//            String building_id = null;
//            if(insertJson.get("building_id") != null){
//                building_id = insertJson.get("building_id").toString();
//                // check if building exist
//                JSONObject checkCriteria = new JSONObject();
//                checkCriteria.put(ObjectTable.KEY_PJ_ID, projectId.substring(2));
//                checkCriteria.put(ObjectTable.KEY_OBJ_TYPE, Const.OBJ_TYPE_BUILDING);
//                checkCriteria.put(ObjectTable.KEY_OBJ_ID, building_id.substring(12));
//                checkCriteria.put(Const.TABLE_KEY_NAME_VALID, true);
//                if(CommonUtil.getCount(HBaseTable.objects, checkCriteria) <= 0)
//                    throw new Exception("建筑体不存在.");
//                // check end.
//            }
//            String category = insertJson.get("equipment_category").toString();
//            String assignedObjId = null;
//            if(insertJson.get("id") != null)
//            {
//                String id = insertJson.get("id").toString();
//                if(id.startsWith("Eq") || id.startsWith("Sy")) {
//                    assignedObjId = id.substring(12);
//                    if (!DpUtils.verifyAssignedObjID(assignedObjId)) {
//                        return DpUtils.errorJsonMsg("指定的id错误.");
//                    }
//                }else
//                    return DpUtils.errorJsonMsg("指定的id错误.");
//            }
//            if(!(EqStaticInfo.sysSet.contains(category) || EqStaticInfo.eqSet.contains(category)))
//                throw new Exception("设备或系统类型不存在");
//            String id = null;
//            ObjectIdName name = new ObjectIdName();
//            if(EqStaticInfo.eqSet.contains(category))
//            {
//                id = ObjectUtil.addObj(projectId.substring(2), Const.OBJ_TYPE_EQUIPMENT, category,
//                        (JSONObject) insertJson.get(Const.JSON_FIELD_JSON_DATA_INFOS), ObjectType.equipment, name, assignedObjId, true);
//            }else {
//                id = ObjectUtil.addObj(projectId.substring(2), Const.OBJ_TYPE_SYSTEM, category,
//                        (JSONObject) insertJson.get(Const.JSON_FIELD_JSON_DATA_INFOS), ObjectType.system, name, assignedObjId, true);
//            }
//            if(building_id != null){
//                //insert building-equipment relation
//                SubsetUtil.addRel(projectId, building_id, id);
//            }
//            return DpUtils.successJsonMsgWithId("", id, name.getNameKey(), name.getNameValue());
//        }catch (Exception ex)
//        {
//            ex.printStackTrace();
//            return DpUtils.errorJsonMsg(ex.getMessage() == null? "添加失败!": ex.getMessage());
//        }
//    }
    @Path("/batch/delete")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String batchDelete(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr){
        try{
            String validateInfo = DpUtils.validateJsonSchema(jsonStr, "jsonSchema/propertyDeleteSchema.json");
            if(validateInfo != null && validateInfo.length() != 0)
                return  DpUtils.errorJsonMsg(validateInfo);
        }catch (Exception ex)
        {
            return DpUtils.errorJsonMsg("输入数据格式错误!");
        }
        JSONObject obj = JSONObject.parseObject(jsonStr);
        JSONArray objects = (JSONArray) obj.get("criterias");
        JSONArray errors = new JSONArray();
        if(objects.size() == 0)
            return PropertyUtil.returnJSON(false, null, errors, "");
        // 删除
        try {
            String pjId = projectId.substring(2);
            ArrayList<String> disableObjs = new ArrayList<>();
            ArrayList<String> deleteObjs = new ArrayList<>();
            PropertyUtil.deleteObjects(pjId, objects, errors, disableObjs, deleteObjs);
            if(objects.size() > 0)
                MessageHandler.publish(String.format("{\"type\":8,\"projectId\":\"%s\",\"name\":\"relationChange\",\"description\":\"\"}", CommonMethods.getProject(projectId,true)));
            // 删除、作废设备下的所有部件
            ObjectUtil.deleteEcUnderEquip(pjId, disableObjs, deleteObjs);
            // 删除、作废设备、系统的所有关系
            ObjectUtil.deleteAllRelation(pjId, deleteObjs);
        }catch (Exception ex)
        {
            return DpUtils.errorJsonMsg("删除失败");
        }
        if(errors.size() > 0)
            return PropertyUtil.returnJSON(objects.size() != 0, null, errors, "");
        return DpUtils.successJsonMsg("删除成功");
    }

    @Path("/delete")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String delete(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr) {
        try {
            //JSONObject criteria = (JSONObject) ((JSONObject) JSONValue.parse(jsonStr)).get("criteria");
            JSONObject criteria = JSONObject.parseObject(jsonStr).getJSONObject("criteria");
            if (criteria.get("id") == null)
                throw new Exception("id错误");
            String id = criteria.get("id").toString();
            CommonUtil.rewriteObjectTableCriteria(projectId.substring(2), criteria, "id");
            if (!((criteria.get(ObjectTable.KEY_OBJ_TYPE).equals(Const.OBJ_TYPE_SYSTEM)) ||
                    (criteria.get(ObjectTable.KEY_OBJ_TYPE).equals(Const.OBJ_TYPE_EQUIPMENT))))
                throw new Exception("id错误");
            CommonUtil.deleteObject(id, criteria.get(ObjectTable.KEY_PJ_ID).toString(), criteria.get(ObjectTable.KEY_OBJ_TYPE).toString()
                    , criteria.get(ObjectTable.KEY_OBJ_ID).toString(), criteria.get(ObjectTable.KEY_OBJ_TYPE).equals(Const.OBJ_TYPE_SYSTEM) ? ObjectType.system : ObjectType.equipment, true);
            // 删除跟资产的关联关系
            Set<String> idSet = new HashSet<>();
            idSet.add(id);
            PropertyRelUtil.deleteLinkByEq(projectId, idSet);
            // 开始废除设备下的部件.
            if (id.startsWith(Const.OBJ_TYPE_EQUIPMENT) && !this.logicallyDelComponent(id, projectId)) {
                return DpUtils.errorJsonMsg("删除设备成功, 删除设备部件失败");
            }
            return DpUtils.successJsonMsg("");
        } catch (Exception ex) {
            ex.printStackTrace();
            return DpUtils.errorJsonMsg(ex.getMessage());
        }
    }

    //删除设备的部件
    private boolean logicallyDelComponent(String eqId, String pjId){
        EqStaticInfo eqStaticInfo = new EqStaticInfo(pjId);
        HashSet<String> set = new HashSet<>();
        set.add("Ec");
        List<String> ecIds = SubsetUtil.getSubset(pjId, eqId, set, new CommonQueryCriteria(), eqStaticInfo);
        if(ecIds == null){
            return true;
        }
        boolean flag = true;
        for (String id : ecIds) {
            String jsonStr = String.format("{\"criteria\":{\"id\":\"%s\"}}", id);
            if(new Component().delete(pjId, jsonStr).contains("failure")){
                flag = false;
            }
        }
        if(ecIds.size() > 0){
            // 删除跟资产的关联关系
            PropertyRelUtil.deleteLinkByEq(pjId, new HashSet<>(ecIds));
        }
        return flag;
    }

    @Path("/system_query")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String sysQueryByMajor(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr){
        try {
            JSONObject json = JSONObject.parseObject(jsonStr);
            String major = (String) ((JSONObject) json.get("criteria")).get("category");

            ArrayList<String> types = new ArrayList<>();
            types.add(major);
            CommonQueryCriteria cqc = CommonUtil.generateCommonQueryCriteria(json);
            JSONArray result = ObjectUtil.querySystemByCategory(projectId.substring(2), types, cqc, Const.OBJ_TYPE_SYSTEM);
//            for(int i = result.size() - 1; i >= 0; --i){
//                String id = (String) ((JSONObject) result.get(i)).get("id");
//                if(!id.substring(15,17).equals(major))
//                    result.remove(i);
//            }
            return DpUtils.returnJSONArray(result,"");
        } catch (Exception e) {
            e.printStackTrace();
            return DpUtils.errorJsonMsg(Arrays.toString(e.getStackTrace()));
        }
    }

    /**
     * 使用ehCache的设备复杂查询
     * @param projectId 项目Id
     * @param jsonStr 请求post JSON
     * @return 目标结果
     */
    @Path("/complex_query")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String complex_query(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr) {
        try {
            EqStaticInfo eqStaticInfo = new EqStaticInfo(projectId);
            JSONObject json =  JSONObject.parseObject(jsonStr);
            CommonQueryCriteria cqc = CommonUtil.generateCommonQueryCriteria(json);
            Boolean nodata = cqc.getNodata();
            cqc.setNodata(false);
            
            if(!json.containsKey("criteria"))
                throw new Exception("缺少criteria.");
            JSONObject criteria = (JSONObject) json.get("criteria");
            String match = null, buildingId = projectId, category = null;
            if(criteria.get("building_id") != null)
            {
                buildingId = criteria.get("building_id").toString();
                if(!buildingId.startsWith("Bd") && !buildingId.startsWith("Pj"))
                {
                    throw new Exception("building_id");
                }
            }
            if(criteria.get("name")!= null && !criteria.get("name").equals(""))
            {
                match = criteria.get("name").toString();
            }
            JSONArray jsonResult = null;
            JSONArray result;
            // 按设备编码查询
            if(criteria.containsKey("equipment_category") && criteria.get("equipment_category")!= null){
                String equipmentCategory = criteria.get("equipment_category").toString();
                result = CacheUtil.complexQueryByCategory(projectId.substring(2), equipmentCategory, buildingId, match, cqc);
                jsonResult =  result;
            }
            // 按照系统编码查询
            else if(criteria.containsKey("system_category") && criteria.get("system_category")!= null){
                String systemCategory = criteria.get("system_category").toString();
                result = CacheUtil.complexQueryByCategory(projectId.substring(2), systemCategory, buildingId, match, cqc);
                jsonResult =  result;
            }
            else if(criteria.containsKey("category") && criteria.get("category")!= null)   // 按专业查询
            {
                category = criteria.get("category").toString();
                if(!(category.length() == 2 && eqStaticInfo.getMajorToEqMap().containsKey(category)) &&        // 是否2位专业编码
                    !((category.length() == 4 || category.length() == 6) && eqStaticInfo.getCateToMajorMap().containsKey(category.substring(2)))){ // 是否4位系统编码或6位设备编码
                    throw new Exception(category + "不是专业, 系统或设备类型");
                }
//                if(!EqStaticInfo.majorToEqMap.containsKey(category) && !(category.length() < 5 && EqStaticInfo.cateToMajorMap.containsKey(category)))
//                    throw new Exception(category + "不是专业, 系统或设备类型");
                result = CacheUtil.complexQueryByCategory(projectId.substring(2), category.length() > 2 ? category.substring(2) : category, buildingId, match, cqc);
                jsonResult =  result;
            }else if(criteria.containsKey("system_id")&&criteria.get("system_id")!=null)   // 按系统id查询(查询属于该系统的设备中满足条件的返回)
            {
                String system_id = null, graph_id = null, rel_type = null;
                system_id = criteria.get("system_id").toString();
                if(criteria.containsKey("graph_id") && criteria.get("graph_id") != null)
                    graph_id = criteria.get("graph_id").toString();
                else
                    throw new Exception("缺少必要key");
                if(criteria.containsKey("rel_type") && criteria.get("rel_type")!= null)
                    rel_type = criteria.get("rel_type").toString();
                else
                    throw new Exception("缺少必要key");
                result = CacheUtil.complexQueryBySystemId(projectId.substring(2), system_id, graph_id, rel_type, match, cqc);
                String resultStr = result.toString();
                jsonResult =  JSONArray.parseArray(resultStr);
            }else if(criteria.keySet().size() == 0){   // 空条件, 查询全部
                result = CacheUtil.complexQueryAll(projectId.substring(2), cqc);
                String resultStr = result.toString();
                jsonResult =  JSONArray.parseArray(resultStr);
            }else if(criteria.keySet().size() == 1 && criteria.containsKey("building_id") && criteria.get("building_id") != null){
                result = CacheUtil.complexQueryByCategory(projectId.substring(2), null, buildingId, match, cqc);
                String resultStr = result.toString();
                jsonResult =  JSONArray.parseArray(resultStr);
            }else if(criteria.keySet().size() == 1 && criteria.containsKey("name") && criteria.get("name") != null){
                result = CacheUtil.complexQueryByCategory(projectId.substring(2), null, buildingId, match, cqc);
                String resultStr = result.toString();
                jsonResult =  JSONArray.parseArray(resultStr);
            }else
                throw new Exception("缺少必要key或key值不正确");
            if(nodata)
                return DpUtils.returnJSONArray(new JSONArray(), "", cqc.getSkip_totalCount());
            return  DpUtils.returnJSONArray(jsonResult, cqc.getSkip_totalCount());
        }catch (Exception ex)
        {
            ex.printStackTrace();
            return DpUtils.errorJsonMsg(ex.getMessage());
        }
    }
    
//    @Path("/complex_query_old")
//    @POST
//    @Produces(MediaType.APPLICATION_JSON)
//    public String complexQueryEq(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr) {
//        try {
//            JSONObject json =  JSONObject.parseObject(jsonStr);
//            CommonQueryCriteria cqc = CommonUtil.generateCommonQueryCriteria(json);
//            if(!json.containsKey("criteria"))
//                throw new Exception("缺少criteria.");
//            JSONObject criteria = (JSONObject) json.get("criteria");
//            String match = null, buildingId = projectId, category = null;
//            if(criteria.get("building_id") != null)
//            {
//                buildingId = criteria.get("building_id").toString();
//                if(!buildingId.startsWith("Bd") && !buildingId.startsWith("Pj"))
//                {
//                    throw new Exception("building_id");
//                }
//            }
//            if(criteria.containsKey("name") && criteria.get("name")!= null && !criteria.get("name").equals(""))
//            {
//                match = criteria.get("name").toString();
//            }
//            if(criteria.containsKey("category") && criteria.get("category")!= null)   // 按专业查询
//            {
//                category = criteria.get("category").toString();
//                JSONArray result = ObjectUtil.complexQueryByCategory(projectId.substring(2), category, buildingId, match, cqc);
//                if(cqc.getNodata())
//                    return DpUtils.returnJSONArray(result, "", cqc.getCount(), cqc.getSkip_totalCount());
//                return DpUtils.returnJSONArray(result, cqc.getSkip_totalCount());
//            }else if(criteria.containsKey("system_id")&&criteria.get("system_id")!=null)   // 按系统id查询(查询属于该系统的设备中满足条件的返回)
//            {
//                String system_id = null, graph_id = null, rel_type = null;
//                system_id = criteria.get("system_id").toString();
//                if(criteria.containsKey("graph_id") && criteria.get("graph_id") != null)
//                    graph_id = criteria.get("graph_id").toString();
//                else
//                    throw new Exception("缺少必要key");
//                if(criteria.containsKey("rel_type") && criteria.get("rel_type")!= null)
//                    rel_type = criteria.get("rel_type").toString();
//                else
//                    throw new Exception("缺少必要key");
//                JSONArray result = ObjectUtil.complexQueryBySystemId(projectId.substring(2), system_id, graph_id, rel_type, match, cqc);
//                if(cqc.getNodata())
//                    return DpUtils.returnJSONArray(result, "", cqc.getCount(), cqc.getSkip_totalCount());
//                return  DpUtils.returnJSONArray(result, cqc.getSkip_totalCount());
//            }else
//                throw new Exception("缺少必要key");
//        }catch (Exception ex)
//        {
//            ex.printStackTrace();
//            return DpUtils.errorJsonMsg(ex.getMessage());
//        }
//    }

    /**
     *<p>Description: 批量新增 .</p>
     *<p> @param jsonStr
     *<p> @return String
     * @since 2018年4月2日: 下午4:13:52
     * @author <a href="mail to:xubin_1009@sina.com">xubin</a>
     * @version 1.0
     */
    @Path("/batch_create")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String batch_create(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr) {
        JSONObject json = JSONObject.parseObject(jsonStr);
        com.sagacloud.json.JSONArray arrEqIds = (com.sagacloud.json.JSONArray) json.get("criteria");
        if (null != arrEqIds && arrEqIds.size() > 0) {
            for (int i = 0; i < arrEqIds.size(); i++) {
                try {
                    this.create(projectId, arrEqIds.get(i).toString());
                }catch(Exception ex) {
                    return DpUtils.errorJsonMsg(ex.getMessage() == null? "添加失败!": ex.getMessage());
                }
            }
        }
        // TODO 返回消息需要重新构造 需要确认
        return DpUtils.successJsonMsg("");
    }
}
