//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.validation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.util.AssociationHelper;

/**
 * This class handles upward reachable info for circular dependency checking
 * 
 * @author Weiping Lu
 * @since 1.2
 */
public class UpwardReachableInfo implements IDependencyInfo {

	private DependencyInfoMgr mgr;
	private MethodElement element;
	private HashMap parentMap;
	private boolean complete = false;
	private boolean debug = false;
	
	protected UpwardReachableInfo(DependencyInfoMgr mgr, MethodElement element) {
		this.mgr = mgr;
		this.element = element;
	}
	
	public boolean isComplete() {
		return complete;
	}
	
	public void build(boolean checkCircular) {
		if (debug) {
			System.out.println("LD> build: " + this);	//$NON-NLS-1$
		}
		buildInner(checkCircular);
	}
	
	private void buildInner(boolean checkCircular) {
		Object info = mgr.getProcessedInfo(element);
		if (info != null) {
			if (info == this && complete) {
				return;
			}
			throw new RuntimeException("Internal error in buildInner: " + info);		//$NON-NLS-1$
		}
		mgr.addToProcessed(this);
		if (debug) {
			System.out.println("LD> buildInner: " + this);	//$NON-NLS-1$
			System.out.println("");							//$NON-NLS-1$
		}
		buildInner_(checkCircular);
	}
	
	private void buildInner_(boolean checkCircular) {
		List parents = getMixedParentList();
		int sz = parents == null ? 0 : parents.size();
		if (sz == 0) {
			complete = true;
			return;
		}
		
		parentMap = new HashMap();
		List processedParents = null;
		for (int i = 0; i< sz; i++) {
			MethodElement parentElem = (MethodElement) parents.get(i);
			UpwardReachableInfo pinfo = (UpwardReachableInfo) mgr.getProcessedInfo(parentElem);
			if (pinfo == null){
				pinfo = new UpwardReachableInfo(mgr, parentElem);
				parentMap.put(parentElem.getGuid(), pinfo);
				pinfo.buildInner(checkCircular);
			} else {
				parentMap.put(parentElem.getGuid(), pinfo);
				if (checkCircular) {
					if (processedParents == null) {
						processedParents = new ArrayList();
					}
					processedParents.add(pinfo);
				}
			}
		}
		complete = true;
			
		if (checkCircular && processedParents != null) {
			for (int i=0; i<processedParents.size(); i++) {
				reachableBy((IDependencyInfo) processedParents.get(i));
			}
		}
	}
	
	public boolean reachableBy(IDependencyInfo info)  {
		if (! (info instanceof UpwardReachableInfo)) {
			throw new UnsupportedOperationException();
		}
		if (debug) {
			System.out.println("LD> Entry reachableBy: this -> " + this);	//$NON-NLS-1$
			System.out.println("LD> Entry reachableBy: info -> " + info);	//$NON-NLS-1$
			System.out.println("");											//$NON-NLS-1$
		}
		return reachableBy((UpwardReachableInfo) info, new Stack(), new HashMap());
	}
	
	private boolean reachableBy(UpwardReachableInfo info, Stack stack, Map seen)  {
		stack.push(info);
		if (debug) {
			System.out.println("LD> reachableBy: this -> " + this);		//$NON-NLS-1$
			System.out.println("LD> reachableBy: info -> " + info);		//$NON-NLS-1$
			System.out.println("");										//$NON-NLS-1$
		}
		boolean ret =  reachableBy_(info, stack, seen);
		stack.pop();
		return ret;
	}
	
	private boolean reachableBy_(UpwardReachableInfo info, Stack stack, Map seen)  {
		Map testMap = info.parentMap;		
		if (testMap == null || testMap.isEmpty()) {
			return false;
		}
		
		if (testMap.containsKey(element.getGuid())) {
			if (debug) {
				System.out.println("LD> Contained in parentMap of: " + info);		//$NON-NLS-1$									
			}
			stack.push(this);
			mgr.logCircularDependency((Stack) stack.clone());
			stack.pop();
			return true;
		}
		
		if (seen.containsKey(info.getElement().getGuid())) {
			return false;
		}
		
		
		seen.put(info.getElement().getGuid(), info);
		
		for (Iterator it = testMap.values().iterator(); it.hasNext();) {
			UpwardReachableInfo parentInfo = (UpwardReachableInfo) it.next();
			if (parentInfo.containedIn(stack)) {
				if (debug) {
					System.out.println("LD> containedIn stack: " + info);		//$NON-NLS-1$									
				}
				stack.push(parentInfo);
				mgr.logCircularDependency((Stack) stack.clone());
				stack.pop();
				return true;
			}
			if  (reachableBy(parentInfo, stack, seen)) {
				return true;
			}
		}	
		
		return false;
	}
	
	public MethodElement getElement() {
		return element;
	}
	
	private List getMixedParentList() {
		List list = new ArrayList();
		collectParentList(element, list);
		VariabilityElement ve = (VariabilityElement) element;
		collectParentListByVariantPaths(ve, list);
		if (ve.getVariabilityType() == VariabilityType.REPLACES ) {
			mgr.addToReplacerMap(this);
		}
		return list;
	}
	
	private void collectParentList(MethodElement elem, List list) {
		List parentList = getParentList(elem);
		
		int sz = parentList == null ? 0 : parentList.size();
		if (mgr.isMoveElement(elem)) {
			if (sz > 1 && !(elem instanceof CustomCategory)) {
				throw new UnsupportedOperationException();	
			}
		} else if (sz > 0) {
			list.addAll(parentList);
		}

	}

	public static List getParentList(MethodElement elem) {
		List parentList = null;
		
		if (elem instanceof CustomCategory) {
			parentList = AssociationHelper.getCustomCategories((CustomCategory) elem);
		} else if (elem instanceof Deliverable) {
			parentList = AssociationHelper.getDeliverables((Deliverable) elem);			
		} else {	
			Object parent = getSameTypeParent(elem);
			if (parent != null) {
				parentList = new ArrayList();
				parentList.add(parent);
			}
		}
		return parentList;
	}
	
	private void collectParentListByVariantPaths(VariabilityElement ve, List list) {
		if (! mgr.isFilterElement(ve)) {
			VariabilityElement parentVe = ve.getVariabilityBasedOnElement();
			VariabilityType type = parentVe == null ? null : ve.getVariabilityType();
			if (type == VariabilityType.CONTRIBUTES || type == VariabilityType.REPLACES) {
				list.add(parentVe);
			}
		}

		if (mgr.isDndElement(ve)) {
			return;
		}
				
		for (Iterator it = TngUtil.getImmediateVarieties(ve, VariabilityType.EXTENDS) ; it.hasNext();) {
			VariabilityElement extender = (VariabilityElement) it.next();
			if (! mgr.isFilterElement(extender)) {
				list.add(extender);
			}
		}
		
	}
	
	private static MethodElement getSameTypeParent(MethodElement elem) {
		if (elem instanceof Activity) {
			return ((Activity) elem).getSuperActivities();
		}
			
		MethodElement parent = (MethodElement) elem.eContainer();
		return parent.getType() == elem.getType() ? parent : null;
	}		
	
	public String toString() {
		return TngUtil.getLabelWithPath(element);
	}
	
	public boolean inheritAncestor(VariabilityType type) {
		VariabilityElement parentVe = ((VariabilityElement) element).getVariabilityBasedOnElement();
		if (parentVe == null) {
			return false;
		}
		if (((VariabilityElement) element).getVariabilityType() != type) {
			return false;
		}
		ArrayList mixParentList = new ArrayList();	
		collectParentList(element, mixParentList);
		if (mixParentList != null && mixParentList.contains(parentVe)) {
			return true;
		}

		UpwardReachableInfo parentVeInfo = (UpwardReachableInfo) parentMap.get(parentVe.getGuid());
		for (Iterator it = parentMap.values().iterator(); it.hasNext();) {
			UpwardReachableInfo parentInfo = (UpwardReachableInfo) it.next();
			if  (parentVeInfo == parentInfo) {
				continue;
			}
			if (parentVeInfo.reachableBy(parentInfo)) {
				return true;
			}
		}
				
		return false;
	}
	
	//This would scale up for performance when infoList gets large
	private boolean containedIn(List infoList) {
		int sz = infoList == null ? 0 : infoList.size();
		if (sz == 0) {
			return false;
		}
		String guid = getElement().getGuid();
		if (sz == 1) {
			return guid.equals(((IDependencyInfo) infoList.get(0)).getElement().getGuid());
		}
		Map listMap = new HashMap();
		for (int i=0; i<sz; i++) {
			IDependencyInfo info = (IDependencyInfo) infoList.get(i);
			listMap.put(info.getElement().getGuid(), info);
		}
		
		return listMap.containsKey(guid);
	}
	
}
