package com.sagacloud.utils.objects;
/*
 * Author: Jxing
 * Create Time: 2018/9/7
 */

import com.sagacloud.cache.cachedObject.QueryObjects;
import com.sagacloud.cache.cachedObject.pojo.ObjectTableObject;
import com.sagacloud.cache.cachedObject.pojo.ObjectTableObjectMap;
import com.sagacloud.cache.utils.CacheUtil;
//import com.sagacloud.json.JSONArray;
//import com.sagacloud.json.JSONObject;
import com.alibaba.fastjson.*;
import com.sagacloud.dict.EqStaticInfo;
import com.sagacloud.utils.CommonMethods;
import com.sagacloud.utils.relationUtils.RelationUtil;
import com.sagacloud.utils.relationUtils.SubsetUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class OutsideGraphQueryProcessor {
    public static JSONArray Query(String projectId, String id, String graphId, String relType, String cFromId, String cToId, long side, Set<String> typeSet, boolean isExclude, CommonQueryCriteria cqc) throws Exception {
        JSONObject object = new JSONObject();
        JSONObject criteria = new JSONObject();
        criteria.put("graph_id", graphId);
        criteria.put("rel_type", relType);
        object.put("criteria", criteria);
        //long time1 = System.currentTimeMillis();
        JSONArray objectInGraph = RelationUtil.queryRelationByGraphIdRelType(projectId, graphId, relType, cFromId, cToId);
        //time1 = System.currentTimeMillis() - time1;
        //System.out.println("时间消耗:" + time1);
        if((objectInGraph == null || objectInGraph.size() == 0 )&& !isExclude)
            return new JSONArray();
        Set<String> idSet = new HashSet<>();
        EqStaticInfo eqStaticInfo = new EqStaticInfo(projectId);
        for(int i = 0; i < objectInGraph.size(); ++i){
            JSONObject singleRel = (JSONObject) objectInGraph.get(i);
            if(side <= 0){
                String fromId = (String) singleRel.get("from_id");
                if(fromId != null && !idSet.contains(fromId))
                    idSet.add(fromId);
            }
            if(side >= 0){
                String toId = (String) singleRel.get("to_id");
                if(toId != null && !idSet.contains(toId))
                    idSet.add(toId);
            }
        }
        if(isExclude) {
            Set<String> typeIdSet = getAllIdByTypeFromCache(CommonMethods.getProject(projectId, false), typeSet);
            // 获取所有不在该图实例中的所有id(指定类型)
            typeIdSet.removeAll(idSet);
            if (typeIdSet.size() == 0)
                return new JSONArray();

            if (!id.startsWith("Pj")) {
                ArrayList<String> idSubsetArray = SubsetUtil.getSubset(projectId, id, typeSet, cqc, eqStaticInfo);
                typeIdSet.retainAll(idSubsetArray);
            }
            return CacheUtil.queryWithPaging(projectId, typeIdSet, cqc);
        }else{
            if (!id.startsWith("Pj")) {
                ArrayList<String> idSubsetArray = SubsetUtil.getSubset(projectId, id, typeSet, cqc, eqStaticInfo);
                idSet.retainAll(idSubsetArray);
            }
            return CacheUtil.queryWithPaging(projectId, idSet, cqc);
        }
    }

    private static Set<String> getAllIdByTypeFromCache(String pjId, Set<String> typeSet) {
        ObjectTableObjectMap cache = QueryObjects.getObjectTableMap(pjId);
        HashMap<String, ObjectTableObject> map = cache.getObjectTableMap();
        Set<String> idSet = new HashSet<>();
        for(String id : map.keySet()){
            ObjectTableObject obj = map.get(id);
            if(typeSet.contains(obj.getObjType())){
                idSet.add(id);
            }else if(obj.getSubType() != null && typeSet.contains(obj.getSubType())){
                idSet.add(id);
            }
        }
        return idSet;
    }

    public static String getDefaultGraphId(String pjId, String graphType) throws Exception {
        String graphId = RelationUtil.getFirstValidGraphInstanceByGraphType(pjId, graphType);
        if(graphId == null){
            throw new Exception("获取图实例异常");
        }else if(graphId.length() == 0){
            throw new Exception(graphType + "图类型下没有可用图实例! 请先添加");
        }
        return graphId;
    }
}
