//------------------------------------------------------------------------------
// 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.MethodPlugin;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.util.AssociationHelper;

/**
 * This class handles plugin dependency info for circular dependency check
 * 
 * @author Weiping Lu
 * @since 1.2
 */
public class PluginDepInfo {

	private PluginDependencyInfoMgr mgr;
	private MethodPlugin plugin;
	private HashMap parentMap;
	private boolean complete = false;
	private boolean debug = false;
	
	protected PluginDepInfo(PluginDependencyInfoMgr mgr, MethodPlugin plugin) {
		this.mgr = mgr;
		this.plugin = plugin;
	}
	
	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(getPlugin());
		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 = getPlugin().getBases();
		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++) {
			MethodPlugin parentElem = (MethodPlugin) parents.get(i);
			PluginDepInfo pinfo = (PluginDepInfo) mgr.getProcessedInfo(parentElem);
			if (pinfo == null){
				pinfo = new PluginDepInfo(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((PluginDepInfo) processedParents.get(i));
			}
		}
	}
	
	public boolean reachableBy(PluginDepInfo info)  {
		if (! (info instanceof PluginDepInfo)) {
			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((PluginDepInfo) info, new Stack(), new HashMap());
	}
	
	private boolean reachableBy(PluginDepInfo 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_(PluginDepInfo info, Stack stack, Map seen)  {
		Map testMap = info.parentMap;		
		if (testMap == null || testMap.isEmpty()) {
			return false;
		}
		
		if (testMap.containsKey(getPlugin().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.getPlugin().getGuid())) {
			return false;
		}
		
		
		seen.put(info.getPlugin().getGuid(), info);
		
		for (Iterator it = testMap.values().iterator(); it.hasNext();) {
			PluginDepInfo parentInfo = (PluginDepInfo) 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 MethodPlugin getPlugin() {
		return plugin;
	}
				
	public String toString() {
		return TngUtil.getLabelWithPath(plugin);
	}
	
	//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 = getPlugin().getGuid();
		if (sz == 1) {
			return guid.equals(((PluginDepInfo) infoList.get(0)).getPlugin().getGuid());
		}
		Map listMap = new HashMap();
		for (int i=0; i<sz; i++) {
			PluginDepInfo info = (PluginDepInfo) infoList.get(i);
			listMap.put(info.getPlugin().getGuid(), info);
		}
		
		return listMap.containsKey(guid);
	}
	
}
