class RepositoryResourceServiceImpl implements RepositoryResourceService {

	@Override
	public List<RepositoryResource> findChildren(Repository project, Integer parentResourceId) {
		if(project == null) {
			return new ArrayList<RepositoryResource>();
		}
		
		List<RepositoryResource> result = repositoryResourceDao.findByRepositoryIdAndParentIdOrderByResourceTypeAscSeqAsc(project.getId(), parentResourceId);
		if(result.isEmpty()) {
			return new ArrayList<RepositoryResource>();
		}
		
		String relativeDir = parentResourceId == Constant.TREE_ROOT_ID ? "": String.join("/", this.findParentPathes(parentResourceId));
		
		Optional<RepositoryContext> RepositoryContext = propertyService.findStringValue(CmPropKey.BLOCKLANG_ROOT_PATH).map(rootDir -> {
			return new RepositoryContext(project.getCreateUserName(), project.getName(), rootDir);
		});
				
		List<GitFileInfo> files = RepositoryContext
				.map(context -> GitUtils.getFiles(context.getGitRepositoryDirectory(), relativeDir))
				.orElse(new ArrayList<GitFileInfo>());
		// 根据文件名关联
		// fileMap 的 key 不包含父目录
		Map<String, GitFileInfo> fileMap = files.stream().collect(Collectors.toMap(GitFileInfo::getName, Function.identity()));
		// fileStatusMap 的 key 中包含父目录，所有父目录
		Map<String, GitFileStatus> fileStatusMap = RepositoryContext
				.map(context -> GitUtils.status(context.getGitRepositoryDirectory(), relativeDir))
				.orElse(Collections.emptyMap());
		
		result.forEach(resource -> {
			if(StringUtils.isBlank(resource.getName())) {
				resource.setName(resource.getKey());
			}
			GitFileInfo fileInfo = null;
			GitFileStatus status = null;
			if(resource.isGroup()) {
				// 当文件夹未跟踪时，则下面的子文件夹不会再在查询结果中，但也可以归为未跟踪。
				// 所以，如果找不到当前文件夹的状态，则继承父文件夹的状态
				String path = null;
				if(StringUtils.isBlank(relativeDir)) {
					path = resource.getKey();
				} else {
					path = relativeDir + "/" + resource.getKey();
				}
				fileInfo = fileMap.get(resource.getKey());
				status = fileStatusMap.get(path);
				
				// 查找子节点的状态
				// 如果目录中同时有新增和修改，则显示修改颜色
				// 如果目录中只有新增，则显示新增颜色
				if(status == null) {
					for(Map.Entry<String, GitFileStatus> entry : fileStatusMap.entrySet()) {
						if(!entry.getKey().equals(path) && entry.getKey().startsWith(path + "/")) {
							if(entry.getValue() == GitFileStatus.MODIFIED || entry.getValue() == GitFileStatus.CHANGED) {
								status = entry.getValue();
								break;
							} else if(entry.getValue() == GitFileStatus.UNTRACKED || entry.getValue() == GitFileStatus.ADDED) {
								status = entry.getValue();
							}
						}
					}
				}
				
				if(status == GitFileStatus.UNTRACKED) {
					// 如果文件夹下有未跟踪的内容，则显示为未跟踪，否则设置为 null
					boolean hasUntrackedFile = false;
					for(Map.Entry<String, GitFileStatus> entry : fileStatusMap.entrySet()) {
						if(!entry.getKey().equals(path) && entry.getKey().startsWith(path + "/")) {
							if(entry.getValue() == GitFileStatus.UNTRACKED) {
								hasUntrackedFile = true;
								break;
							}
						}
					}
					if(!hasUntrackedFile) {
						status = null;
					}
				}
				
				// 此时是多级目录都没有跟踪
				if(fileInfo == null && status == null) {
					// 目录没有被跟踪，则不显示状态信息
				}
				
			} else {
				String path = null;
				if(StringUtils.isBlank(relativeDir)) {
					path = resource.getFileName();
				} else {
					path = relativeDir + "/" + resource.getFileName();
				}
				fileInfo = fileMap.get(resource.getFileName());
				status = fileStatusMap.get(path);
			}
			
			if(fileInfo != null) {
				resource.setLatestCommitId(fileInfo.getCommitId());
				resource.setLatestCommitTime(fileInfo.getLatestCommitTime());
				resource.setLatestShortMessage(fileInfo.getLatestShortMessage());
				resource.setLatestFullMessage(fileInfo.getLatestFullMessage());
			}
			resource.setGitStatus(status);
		});
		
		return result;
	}

}