package com.blueland.bpm.engine.core.service;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.collections.MultiMap;
import org.springframework.core.io.ResourceLoader;

import com.blueland.bpm.common.page.Page;
import com.blueland.bpm.engine.core.model.ActivityDefinitionModel;
import com.blueland.bpm.engine.core.model.ActivityResourceModel;
import com.blueland.bpm.engine.core.model.ProcessDefinitionModel;
import com.blueland.bpm.engine.core.model.SearchProcessListDTO;

/**
 * 流程定义Service
 * @version: 1.0
 * @author lw
 */
public interface ProcessDefinitionService extends ActivitiService{
	/**
	 * 根据流程实例ID查询流程定义对象{@link ProcessDefinition}
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public ProcessDefinitionModel getProcessDefByPid(String processInstanceId);

	/**
	 * 根据流程定义ID查询流程定义对象{@link ProcessDefinition}
	 * 
	 * @param processDefinitionId
	 *            流程定义对象ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public ProcessDefinitionModel getProcessDef(String processDefinitionId);
	/**
	 * 获取流程所有环节
	 * @param processDefinitionId
	 * @return
	 */
	public List<ActivityDefinitionModel> getProcessActivitys(String processDefinitionId);
	/**
	 * 获取流程所有用户任务环节
	 * @param processDefinitionId
	 * @return
	 */
	public List<ActivityDefinitionModel> getProcessUserActivitys(String processDefinitionId);
	
	
	/**
	 * 获取开始环节
	 * @param processDefinitionId
	 * @return
	 */
	public ActivityDefinitionModel getStartActivity(String processDefinitionId);
/**
 * 获取环节对象
 * @param processDefinitionId
 * @param activityId
 * @return
 */
	public ActivityDefinitionModel getActivity(String processDefinitionId,
			String activityId);
/**
 * 获取下一步环节列表
 * @param processInstId
 * @param processDefinitionId
 * @param activityId
 * @param conditionMap
 * @return
 */
	public List<ActivityDefinitionModel> getNextActivity(String processInstId,String processDefinitionId,
			String activityId, Map conditionMap);
	
	/**
	 * 获取补发撤销下一步环节列表
	 * @param processInstId
	 * @param processDefinitionId
	 * @param activityId
	 * @param conditionMap
	 * @return
	 */
	public List<ActivityDefinitionModel> getMultiActivity(String processInstId,String processDefinitionId,
				String activityId, Map conditionMap);
		
	/**
	 * 获取上一环节列表
	 * @param processDefinitionId
	 * @param activityId
	 * @param conditionMap
	 * @return
	 */
	public List<ActivityDefinitionModel> getPrevActivity(String processDefinitionId,
			String activityId, Map conditionMap);
	/**
	 * 获取环节用户列表
	 * @param processInstId
	 * @param processDefinitionId
	 * @param curActivityId
	 * @param curActInstId
	 * @param destActivityId
	 * @param userId
	 * @param filterIds
	 * @return
	 */
	public List<ActivityResourceModel> getActivityUserTree(String processInstId,String processDefinitionId,
			String curActInstId, String curActivityId,String destActivityId,String userId,String userOrgId,List<String> filterIds,Map conditionMap) ;

	/**
	 * 获取指定环节绑定资源
	 * 
	 * @param activityDefinitionModel
	 * @return
	 */
	public List<ActivityResourceModel> getResource(String procDefId,String actDefId);

	/**
	 * 按条件 查询流程定义列表
	 * @param SearchProcessListDTO
	 * @return Page
	 */
	public Page<List> findProcessDefList(SearchProcessListDTO searchProcessList);
	
	
	/**
	 * 按条件 查询流程定义列表
	 * @param SearchProcessListDTO
	 * @return List
	 */
	public List<ProcessDefinitionModel> findProcessDefs(SearchProcessListDTO searchProcessList) ;
	
	public List<ProcessDefinitionModel> findProcessDefsNotCascide(SearchProcessListDTO searchProcessList);
	/**
	 * 查询指定流程定义key下的所有历史版本模型
	 * @return
	 */
	public List<ProcessDefinitionModel> findAllVersionProcessDefs(String procDefkey);

	/**
	 * 根据流程定义ID查询流程定义对象{@link ProcessDefinition}
	 * 
	 * @param processDefinitionId
	 *            流程定义对象ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public ProcessDefinitionModel getProcessDefBykey(String processDefinitionKey);

	/**
	 * 根据用户ID查询有权限起草的流程定义列表{@link ProcessDefinition}
	 * 
	 * @param userId
	 *            用户ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public Map<String,List<ProcessDefinitionModel>> findProcessDefStartByUser(String tenantId, String userId);
	
	
	/**
	 * 根据用户ID查询有权限起草的流程定义列表{@link ProcessDefinition}
	 * 
	 * @param userId
	 *            用户ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public Map<String,List<ProcessDefinitionModel>> findProcessDefStartByUser(String tenantId, String userId, String flowType);
	
	/**
	 * 根据用户ID查询有权限起草的流程定义列表{@link ProcessDefinition}
	 * 
	 * @param userId
	 *            用户ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public ProcessDefinitionModel getProcessDefStartByUser(String userId,String processDefKey);
	
	/**
	 * 是否有权限起草固定流程
	 * 
	 * @param userId
	 *            用户ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 */
	public boolean isStartProcessPower(String userId,String processDefKey) ;
	/**
	 * 根据用户ID查询有权限起草的流程定义列表{@link ProcessDefinition}
	 * 
	 * @param userId
	 *            用户ID
	 * @return 流程定义对象{@link ProcessDefinition}
	 *//*
	public Page<Object[]> findProcessDefAndDeployList(String userId) ;*/

	/**
	 * 部署classpath下面的流程定义
	 * <p>
	 * 从属性配置文件中获取属性<b>com.blueland.bpm.engine.modules</b>扫描**deployments**
	 * </p>
	 * <p>
	 * 然后从每个**deployments/${module}**查找在属性配置文件中的属性**com.blueland.bpm.engine.module.keys.${
	 * submodule}**
	 * <p>
	 * 配置实例：
	 * 
	 * <pre>
	 * #com.blueland.bpm.engine for deploy
	 * com.blueland.bpm.engine.modules=budget,erp,oa
	 * com.blueland.bpm.engine.module.keys.budget=budget
	 * com.blueland.bpm.engine.module.keys.erp=acceptInsurance,billing,effectInsurance,endorsement,payment
	 * com.blueland.bpm.engine.module.keys.oa=caruse,leave,officalstamp,officesupply,out,overtime
	 * </pre>
	 * 
	 * </p>
	 * 
	 * @param processKey
	 *            流程定义KEY
	 * @throws Exception
	 */
	public void deployFromClasspath(String exportDir, String... processKey);

	

	/**
	 * 部署单个流程定义
	 * 
	 * @param resourceLoader
	 *            {@link ResourceLoader}
	 * @param processKey
	 *            模块名称
	 * @param subModule
	 *            流程定义名称
	 * @throws IOException
	 *             找不到zip文件时
	 */
	public ProcessDefinitionModel deploySingleProcess(String tenantId,InputStream inputStream, String fileName);

	/**
	 * 重新部署单个流程定义
	 * 
	 * @param processKey
	 *            流程定义KEY
	 * @throws Exception
	 * @see #deployFromClasspath
	 */
	public void redeploy(String exportDir, String... processKey);

	/**
	 * 重新部署所有流程定义，调用：{@link #deployFromClasspath()}完成功能
	 * 
	 * @throws Exception
	 * @see #deployFromClasspath
	 */
	public void deployAllFromClasspath(String exportDir) throws Exception ;

	/**
	 * 加载流程定义的bpmn.xml或图片资源
	 * 
	 * @param processDefinitionId
	 *            流程定义ID
	 * @param resourceType
	 *            image:图片资源,xml:bpmn.xml
	 * @return InputStream
	 */
	public InputStream loadProcessResource(String processDefinitionId,
			String resourceType) ;
	/**
	 * 更新流程部署模型
	 * @param deploymentId
	 * @param processDefinitionId
	 * @param resourceByte
	 * @param isUpdateImage
	 */
	public void updateDeploymentResource(String deploymentId,String processDefinitionId,byte[] resourceByte,boolean isUpdateImage);
	/**
	 * 更新流程部署模型并刷新缓存
	 * @param bpmnModel
	 * @param processDefinition
	 * @param isUpdateImage
	 * @return
	 */
	public boolean updateDeploymentResourceAndCache(BpmnModel bpmnModel,ProcessDefinitionModel processDefinition,boolean isUpdateImage);
	/**
	 * 刷新流程缓存
	 * @param processDefinitionId
	 */
	public void refreshProcessDefineCache(String processDefinitionId);
	/**
	 * 删除流程定义
	 * @param procDefId
	 * @param deploymentId
	 * @param cascode
	 * @return
	 */
	public boolean delete(String procDefId, String deploymentId,boolean cascode);
	

	/**
	 * 查询指定资源的值在哪里流程定义中（资源类型包含角色、组织、人员）
	 * 可以按租户或者单个流程定义KEY来查询
	 * @param tenantId		租户ID
	 * @param procDefKey	流程定义
	 * @param type		资源类型
	 * @param resourceVal	资源值
	 * @return
	 */
	public List<Map<String,String>> findProcessDefsByResource(
			String tenantId, String procDefKey, String resourceType, String resourceVal) ;
	

}