package com.persagy.proxy.adm.strategy;

import java.util.*;

import javax.annotation.Resource;

import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists;
import com.persagy.dmp.basic.dto.RequestData;
import com.persagy.dmp.digital.entity.ObjectDigital;
import com.persagy.proxy.adm.constant.AdmRelationType;
import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
import com.persagy.proxy.adm.strategy.relationdata.RelationObjectStrategy;
import com.persagy.proxy.report.model.AdmRelationObject;

/**
 * 获取关系对象的上下文类
 * 
 * @version 1.0.0
 * @company persagy 
 * @author zhangqiankun
 * @date 2021年9月2日 下午10:44:32
 */
@Component
public class RelationObjectContext {

	/**
	 * 策略执行类
	 */
	private Map<String, RelationObjectStrategy> relationObjectStrategyMap;
	
	/**
	 * @param relationObjectStrategyMap
	 */
	@Resource
	public void relationObjectStrategyMap(Map<String, RelationObjectStrategy> relationObjectStrategyMap) {
		this.relationObjectStrategyMap = relationObjectStrategyMap;
	}
	
	/**
	 * 获取关系对象数据
	 * 
	 * @param groupCode
	 * @param projectId
	 * @param relType graphCode_relCode
	 * @return
	 */
	public List<AdmRelationObject> exportRelationObject(String groupCode, String projectId, String relType) {
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		return strategy == null ? Lists.newArrayList() : strategy.exportRelationObject(groupCode, projectId);
	}
	
	/**
	 * 检查关联对象的合法性
	 * 
	 * @param relationObject 当前需要校验的对象
	 * @param groupCode
	 * @param projectId
	 * @param relType graphCode_relCode
	 * @param code 获取对象的依据
	 * @param admRelType ADM定义的类型
	 * @return String - 校验失败的原因， ObjectNode -- BDTP接口的参数，不会返回null，请用instanceOf 判断返回值
	 */
	public Object checkRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String relType, String code, AdmRelationTypeEnum typeEnum) {
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		if (strategy == null && typeEnum != null) {
			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
		}
		return strategy == null ? "不存在此类型" : strategy.beforeSaveRelationObject(relationObject, groupCode, projectId, code, typeEnum);
	}
	/**
	 * 检查关联对象的合法性
	 *
	 * @param relationObjects 当前需要校验的对象
	 * @param groupCode
	 * @param projectId
	 * @param relType graphCode_relCode
	 * @param code 获取对象的依据
	 * @param typeEnum ADM定义的类型
	 * @return String - 校验失败的原因， ObjectNode -- BDTP接口的参数，不会返回null，请用instanceOf 判断返回值
	 */
	public Map<String,Object> checkRelationObjects(List<AdmRelationObject> relationObjects, String groupCode,
												   String projectId, String relType, String code,
												   AdmRelationTypeEnum typeEnum) {
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		if (strategy == null && typeEnum != null) {
			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
		}
		if (null==strategy){
			Map<String,Object> result = new HashMap<>();
			relationObjects.forEach(obj->{
						result.put(StrUtil.toString(obj.getMasterCode())+StrUtil.UNDERLINE+StrUtil.toString(obj.getSlaveCode()),"不存在此类型");
					});
			return result;
		}
		return strategy.beforeSaveRelationObjects(relationObjects, groupCode, projectId, code, typeEnum);
	}

	/**
	 * 批量保存对象之间的关系
	 * 
	 * @param admRelationObject
	 * @param groupCode
	 * @param projectId
	 * @param relType graphCode_relCode
	 * @return 
	 */
	public boolean saveRelationObjects(List<ObjectNode> relationObjects, String groupCode, String projectId, String relType) {
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		if (strategy == null) {
			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
		}
		return strategy == null ? false : strategy.saveRelationObjects(relationObjects, groupCode, projectId);
	}

	/**
	 * 统计关系总数
	 * 
	 * @param groupCode
	 * @param projectId
	 * @param relType graphCode_relCode
	 * @return 
	 */
	public long countRelationObjects(String groupCode, String projectId, String relType, AdmRelationTypeEnum typeEnum) {
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		if (strategy == null && typeEnum != null) {
			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
		}
		return strategy == null ? 0 : strategy.countRelationObjects(groupCode, projectId, typeEnum);
	}

	/**
	 * 查询全部的关系对象数据
	 * 
	 * @param masterObjs 查询的数据集存储地方
	 * @param requestData 请求参数
	 * @param groupCode 集团编码
	 * @param projectId 项目ID
	 * @param relType  graphCode_relCode
	 * @param mainContent	主对象的筛选关键字,筛选范围为id,name,local_id,local_name,cADID.为关系左侧对象
	 * @param slaveContent	从对象的筛选关键字.objTo对应的对象,筛选范围为id,name,local_id,local_name.为关系右侧对象
	 */
	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String relType, String mainContent, Set<String> slaveContent, AdmRelationTypeEnum typeEnum) {
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		if (strategy == null && typeEnum != null) {
			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
		}
		return strategy == null ? Lists.newArrayList() : strategy.queryAllRelations(groupCode, projectId, mainContent, slaveContent, typeEnum);
	}
	
	/**
	 * 分页查询关系对象数据
	 * 
	 * @param masterObjs 查询的数据集存储地方
	 * @param requestData 请求参数
	 * @param groupCode 集团编码
	 * @param projectId 项目ID
	 * @param relType  graphCode_relCode
	 */
	public List<ObjectDigital> queryPageRelations(RequestData requestData, String groupCode, String projectId, String relType) {
		List<ObjectDigital> masterObjs = new ArrayList<ObjectDigital>();
		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
		if (strategy == null) {
			return masterObjs;
		}
		strategy.queryPageRelations(masterObjs, requestData, groupCode, projectId);
		return masterObjs;
	}
	
}
