package com.sagacloud.utils.relationUtils;
/*
 * Author: Jxing
 * Create Time: 2019/2/18
 */

import com.sagacloud.utils.CommonUtil;
import com.sagacloud.utils.Const;
import com.sagacloud.utils.ObjectUtil;
import com.sagacloud.utils.jsonHelper.SubsetEntity;
import com.sagacloud.utils.objects.ObjectType;

import java.util.*;

public class SubsetRelationSubmitter {
    private String projectId;
    private Set<String> checkIdSet;
    List<SubsetEntity> entities = new ArrayList<>();

    // 过滤重复的父节点时的依据
    public static HashMap<ObjectType, Integer> priorityMap = new HashMap<>();
    static {
        // 此处的put, 必须按照ElementSptoSp中的关系类型顺序添加.
        priorityMap.put(ObjectType.building, 1);
        priorityMap.put(ObjectType.floor, 2);
        priorityMap.put(ObjectType.equipment, 2);
    }

    public SubsetRelationSubmitter(String projectId) {
        if (projectId.startsWith(Const.OBJ_TYPE_PROJECT)) {
            this.projectId = projectId.substring(2);
        }else
            this.projectId = projectId;
        checkIdSet = new HashSet<>();
    }

    /**
     * 添加要提交的关系, map的key是fromid, value是toid
     * @param relationMap
     * @param checkKeyOrValue true --> 检查Map的key, false --> 检查Map的value, null是检查key + value
     */
    public void addFrom2To(Map<String, String> relationMap, Boolean checkKeyOrValue) {
        for(String id : relationMap.keySet()){
            entities.add(new SubsetEntity(id, relationMap.get(id)));
            if(checkKeyOrValue == null || checkKeyOrValue.equals(true)){
                checkIdSet.add(id);
            }
            if(checkKeyOrValue == null || checkKeyOrValue.equals(false)){
                checkIdSet.add(relationMap.get(id));
            }
        }
    }

    /**
     * 添加要提交的关系, map的key是toid, value是fromid
     * @param relationMap
     * @param checkKeyOrValue true --> 检查Map的key, false --> 检查Map的value, null是检查key + value
     */
    public void addTo2From(Map<String, String> relationMap, Boolean checkKeyOrValue) {
        for(String id : relationMap.keySet()){
            entities.add(new SubsetEntity(relationMap.get(id), id));
            if(checkKeyOrValue == null || checkKeyOrValue.equals(true)){
                checkIdSet.add(id);
            }
            if(checkKeyOrValue == null || checkKeyOrValue.equals(false)){
                checkIdSet.add(relationMap.get(id));
            }
        }
    }

    public void submit() throws Exception {
        // 验证 valid, checkIdSet 里面存的是invalid对象
        boolean noException = ObjectUtil.filterValid(projectId, checkIdSet, false, null);
        if (!noException)
            throw new Exception("数据库连接异常");
        for(int i = entities.size() - 1 ; i > -1 ; --i){
            SubsetEntity e = entities.get(i);
            if(checkIdSet.contains(e.fromId) || checkIdSet.contains(e.toId)){
                entities.remove(i);
            }
        }
        // 去除subset的父节点在有子节点的情况下
        removeRedundantSuperNode();
        if(entities.size() > 0)
            SubsetUtil.modify(projectId, entities);
    }

    private void removeRedundantSuperNode() {
        Map<String, String> tmpMap = new HashMap<>();
        boolean conflict = false;
        for(int i = entities.size() - 1 ; i > -1 ; --i){
            SubsetEntity e = entities.get(i);
            String key = null, value = null;
            if(CommonUtil.checkType(e.toId, ObjectType.space) || CommonUtil.checkType(e.toId, ObjectType.ispace)
                    || CommonUtil.checkType(e.toId, ObjectType.component)){
                key = e.toId;
                value = e.fromId;
            }else if(CommonUtil.checkType(e.fromId, ObjectType.space) || CommonUtil.checkType(e.fromId, ObjectType.ispace)
                    || CommonUtil.checkType(e.fromId, ObjectType.component)){
                key = e.fromId;
                value = e.toId;
            }
            if(key == null || value == null)
                continue;
            if(tmpMap.containsKey(key)){
                String currentValue = tmpMap.get(key);
                ObjectType currentType = ObjectUtil.getObjectTypeById(currentValue);
                ObjectType valueType = ObjectUtil.getObjectTypeById(value);
                if(valueType == null || currentType == null)
                    continue;
                if(priorityMap.containsKey(valueType) && priorityMap.containsKey(currentType)){
                    if(priorityMap.get(valueType) > priorityMap.get(currentType)) {
                        tmpMap.put(key, value);
                    }
                }
                // 发现有冗余的更高级父级
                conflict = true;
            }else {
                tmpMap.put(key, value);
            }
        }
        if(!conflict)
            return;
        for(int i = entities.size() - 1 ; i > -1 ; --i) {
            SubsetEntity e = entities.get(i);
            if(tmpMap.containsKey(e.fromId)){
                if(!tmpMap.get(e.fromId).equals(e.toId)){
                    entities.remove(i);
                }
            }else if(tmpMap.containsKey(e.toId)){
                if(!tmpMap.get(e.toId).equals(e.fromId)){
                    entities.remove(i);
                }
            }
        }
    }
}
