package com.steerinfo.ems.Utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 树结构闭环判断（用于计算公式的死循环判断）
 * @author yan
 *
 */
public class Tree {
	private String id;
	private String parentid;
	// 是否有下级
	private boolean hasCid;
	
	public Tree(String id, String parentid, boolean hasCid) {
		this.id = id;
		this.parentid = parentid;
		this.hasCid = hasCid;
	}
	
	public Tree() {}
	
	/**
	 * 思路：<br/>
	 * 1、获得所有单一路径 <br/>
	 * 2、路径中有重复节点表示有闭环 <br/>
	 * 3、树节点减去所有路径中节点也表示树数据错误 <br/>
	 * @param tlist 树数据节点集合
	 * @return 树结构是否存在闭环或者数据错误
	 */
	public static boolean isLoop(List<Tree> tlist) {
		List<Tree> ckl = new ArrayList<Tree>();
		ckl.addAll(tlist);
		// 所有路径集合，没有下级点的表示终点，一个终点表示一条路径
		List<List<Tree>> allpath = new ArrayList<List<Tree>>();
		if (ckl.size()>0){
			for(int i = 0;i<ckl.size();i++){
				Tree t = ckl.get(i);
				if(!t.hasCid()){
					List<Tree> ll = new ArrayList<Tree>();
					// 路径新的父节点排在前面
					ll.add(0,t);
					// 增加一条路径
					allpath.add(ll);
				}
			}
		}else{
			return false;
		}
		// 遍历所有路径
		for(int i = 0;i<allpath.size();i++){
			// 取得一条路径
			List<Tree> la = allpath.get(i);
			boolean find = true;
			// 节点还有父节点表示路径未结束，路径中加上节点，路径中发现重复节点表示有闭环
			while(la.get(0).getParentid()!=null && !la.get(0).getParentid().isEmpty() && find){
				find = false;
				for(int j = 0;j<ckl.size();j++){
					Tree tj = ckl.get(j);
					if(tj.getId().equalsIgnoreCase(la.get(0).getParentid())){
						find = true;
						// 路径中发现重复节点表示有闭环
						if (la.contains(tj)){
							return true;
						}else{
							// 在路径最前加上父节点，重复进入while判断
							la.add(0,tj);
						}
					}
				}
			}
			if(!find){
				System.out.println("未找到id:" + la.get(0).getId() + "-parentid:" + la.get(0).getParentid());
				return true;
			}
			// 当所有路径遍历完成，allpath中保存所有路径。
		}
		// 如果节点集合中有节点不在路径中，表示树数据节点集合（tlist）有错误
		for(int i = 0;i<allpath.size();i++){
			List<Tree> la = allpath.get(i);
			for(int j = 0;j<la.size();j++){
				Tree t = la.get(j);
				Iterator<Tree> it = ckl.iterator();
		        while(it.hasNext()){
		        	if(it.next().getId().equals(t.getId())){
		        		it.remove();
		        	}
		        }
			}
		}
//		if(ckl.size()>0){
//			return true;
//		}else{
//			return false;
//		}
		return false;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public boolean hasCid() {
		return hasCid;
	}

	public void setHasCid(boolean hasCid) {
		this.hasCid = hasCid;
	}

	public String getParentid() {
		return parentid;
	}

	public void setParentid(String parentid) {
		this.parentid = parentid;
	}

	public static void main(String[] a){
		List<Tree> l = new ArrayList<Tree>();
		Tree t = new Tree("ZY3100CP63R","",false);
		l.add(t);
		t = new Tree("ZY3200CP64R","",false);
		l.add(t);
		t = new Tree("ZY3000E0011R","",true);
		l.add(t);
		//System.out.println("存在闭：" + l);
		System.out.println("存在闭环或者数据错误：" + isLoop(l));
	}
}
