/*******************************************************************************
 * Copyright (c) 2009, 2019 Xored Software Inc and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     Xored Software Inc - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.rcptt.core.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.rcptt.core.model.IContext;
import org.eclipse.rcptt.core.model.IQ7NamedElement;
import org.eclipse.rcptt.core.model.ITestCase;
import org.eclipse.rcptt.core.model.ITestSuite;
import org.eclipse.rcptt.core.model.ModelException;
import org.eclipse.rcptt.core.model.search.Q7SearchCore;
import org.eclipse.rcptt.core.scenario.NamedElement;
import org.eclipse.rcptt.core.scenario.TestSuiteItem;
import org.eclipse.rcptt.core.workspace.IWorkspaceFinder;
import org.eclipse.rcptt.core.workspace.Q7Utils;
import org.eclipse.rcptt.core.workspace.RcpttCore;
import org.eclipse.rcptt.core.workspace.WorkspaceFinder;
import org.eclipse.rcptt.internal.core.RcpttPlugin;
import org.eclipse.rcptt.internal.core.model.Q7InternalTestCase;

public final class ModelCycleDetector {

	private ModelCycleDetector() {
	}

	public static class CycleGraph {

		public Map<String, List<String>> graph;
		public boolean cycle;
		public HashMap<String, IQ7NamedElement> elementsMap;

	}

	public static boolean hasCycles(IQ7NamedElement[] elements) {
		return buildCycles(elements, null, new NullProgressMonitor()).cycle;
	}

	public static boolean hasCycles(NamedElement... elements) {
		IQ7NamedElement[] els = new IQ7NamedElement[elements.length];
		for (int i = 0; i < els.length; i++) {
			els[i] = (IQ7NamedElement) RcpttCore.create(Q7Utils.getLocation(elements[i]));
		}
		return hasCycles(els);
	}

	public static CycleGraph buildCycles(IQ7NamedElement[] elements,
			IWorkspaceFinder finder, IProgressMonitor monitor) {
		try {
			CycleGraph gr = new CycleGraph();
			gr.graph = new HashMap<String, List<String>>();
			gr.elementsMap = new HashMap<String, IQ7NamedElement>();

			monitor.beginTask("Check for circular dependencies",
					elements.length + 1);
			for (IQ7NamedElement element : elements) {
				if (monitor.isCanceled()) {
					return gr;
				}
				if (element instanceof ITestCase) {
					addScenarioToGraph((ITestCase) element, gr, finder);
				} else if (element instanceof IContext) {
					addContextToGraph((IContext) element, gr, finder);
				} else if (element instanceof ITestSuite) {
					addTestSuiteToGraph((ITestSuite) element, gr, finder);
				}
				monitor.worked(1);
			}
			int prevVal = 0;
			while (true) {
				if (monitor.isCanceled()) {
					return gr;
				}
				processGraph(gr.graph);
				if (gr.graph.size() == prevVal) {
					break;
				}
				prevVal = gr.graph.size();
			}
			gr.cycle = (gr.graph.size() >= 2);
			return gr;
		} finally {
			monitor.done();
		}
	}

	private static void processGraph(Map<String, List<String>> graph) {
		Set<Entry<String, List<String>>> nodes = graph.entrySet();
		for (Iterator<Entry<String, List<String>>> it = nodes.iterator(); it
				.hasNext();) {
			Entry<String, List<String>> entry = it.next();
			List<String> childIds = entry.getValue();
			for (Iterator<String> it2 = childIds.iterator(); it2.hasNext();) {
				String childId = it2.next();
				if (!graph.containsKey(childId)) {
					it2.remove();
				}
			}

			if (childIds.size() == 0) {
				it.remove();
			}
		}
	}

	private static void addContextToGraph(IContext context,	CycleGraph graph, IWorkspaceFinder finder) {
		IContext[] children = RcpttCore.getInstance().getContexts(context, finder, true);
		try {
			String cid = getIdBy(context);
			graph.elementsMap.put(cid, context);
			for (IContext child : children) {
				if (!RcpttCore.getInstance().getContextReferences(child).isEmpty()) {
					List<String> childIds = graph.graph.get(cid);
					if (childIds == null) {
						childIds = new ArrayList<String>();
						graph.graph.put(cid, childIds);
					} else if (childIds.contains(getIdBy(child))) {
						continue;
					}
					childIds.add(getIdBy(child));
					addContextToGraph(child, graph, finder);
				}
			}
		} catch (ModelException e) {
			RcpttPlugin.log(e);
		}
	}

	private static void addTestSuiteToGraph(ITestSuite suite,
			CycleGraph graph, IWorkspaceFinder finder) {
		TestSuiteItem[] items;
		if (finder == null) {
			finder = WorkspaceFinder.getInstance();
		}
		try {
			items = suite.getItems();
			try {
				String cid = getIdBy(suite);
				graph.elementsMap.put(cid, suite);
				if (items != null && items.length > 0) {
					List<String> childIds = graph.graph.get(cid);
					for (TestSuiteItem testSuiteItem : items) {
						String childID = testSuiteItem.getNamedElementId();
						if (childIds != null && childIds.contains(childID)) {
							continue;
						} else {
							if (childIds == null) {
								childIds = new ArrayList<String>();
								graph.graph.put(cid, childIds);
							}
							childIds.add(childID);
							ITestCase[] cases = finder.findTestcase(suite,
									childID);
							if (cases != null) {
								for (ITestCase iTestCase : cases) {
									addScenarioToGraph(iTestCase, graph,
											finder);
								}
							}
							ITestSuite[] suites = finder.findTestsuites(
									suite, childID);
							if (suites != null) {
								for (ITestSuite testSuite : suites) {
									addTestSuiteToGraph(testSuite, graph,
											finder);
								}
							}
						}
					}
				}
			} catch (ModelException e) {
				RcpttPlugin.log(e);
			}
		} catch (ModelException e1) {
			RcpttPlugin.log(e1);
		}
	}

	private static String getIdBy(IQ7NamedElement context)
			throws ModelException {
		String cid = Q7SearchCore.findIDByDocument(context);
		if (cid == null) {
			cid = context.getID();
		}
		return cid;
	}

	private static void addScenarioToGraph(ITestCase scenario,
			CycleGraph graph, IWorkspaceFinder finder) {
		if (scenario instanceof Q7InternalTestCase) {
			return;
		}
		try {
			if (!scenario.exists()) {
				return;
			}
		} catch (Exception e) {
			RcpttPlugin.log(e);
			return;
		}
		IContext[] contexts = RcpttCore.getInstance().getContexts(scenario, finder, true);
		for (IContext c : contexts) {
			if (!RcpttCore.getInstance().isNotGroupOrSuperOrCapabilityContext(c)) {
				addContextToGraph(c, graph, finder);
			}
		}
	}
}
