/*******************************************************************************
 * Copyright (c) 2015, 2018 Willink Transformations 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
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   E.D.Willink - Initial API and implementation
 *******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvtb2qvts;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.utilities.TracingOption;
import org.eclipse.qvtd.compiler.CompilerConstants;
import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
import org.eclipse.qvtd.pivot.qvtschedule.Edge;
import org.eclipse.qvtd.pivot.qvtschedule.MappingRegion;
import org.eclipse.qvtd.pivot.qvtschedule.NavigationEdge;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;

import com.google.common.collect.Sets;

/**
 * RuleHeadAnalysis is a helper class to compute the head nodes of a region.
 */
public class RuleHeadAnalysis extends HeadAnalysis
{
	public static final @NonNull TracingOption RULE_HEAD_NODE_GROUPS = new TracingOption(CompilerConstants.PLUGIN_ID, "qvts2qvts/partition/headNodeGroups");

	/**
	 * Return the minimal head(s) of a partitioned MappingRegion from which all old nodes in the region may be reached by to-one navigation.
	 *
	 * The head/not-head nodes are installed by invoking Node.setHead(true/false) as appropriate.
	 *
	 * FIXME is this an unduely complicated way of computing the traceNode ??
	 */
	public static @NonNull Iterable<@NonNull Node> computeRealizedHeadNodes(@NonNull MappingRegion mappingRegion, @NonNull List<@NonNull Node> realizedMiddleNodes) {
		RuleHeadAnalysis mappingRegionAnalysis = new RuleHeadAnalysis(mappingRegion);
		Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSourceClosure = mappingRegionAnalysis.computeNewTargetFromSources(realizedMiddleNodes);
		Iterable<@NonNull Node> headNodes = mappingRegionAnalysis.computeHeadNodes(targetFromSourceClosure, null);
		return headNodes;
	}

	/**
	 * Return the minimal head(s) of a MappingRegion from which all old nodes in the region may be reached by to-one navigation.
	 *
	 * This uni-directional analysis is performed after the trace nodes are synthesized and so can exploit to-one traces to
	 * locate output nodes wrt input nodes.
	 *
	 * The head/not-head nodes are installed by invoking Node.setHead(true/false) as appropriate.
	 */
	public static @NonNull Iterable<@NonNull Node> computeRuleHeadNodes(@NonNull ScheduleManager scheduleManager, @NonNull MappingRegion mappingRegion, @Nullable List<@NonNull Node> preferredHeadNodes) {
		RuleHeadAnalysis mappingRegionAnalysis = new RuleHeadAnalysis(mappingRegion);
		Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSources =  mappingRegionAnalysis.computeOldTargetFromSources();
		Iterable<@NonNull Node> headNodes =  mappingRegionAnalysis.computeHeadNodes(targetFromSources, preferredHeadNodes);
		mappingRegionAnalysis.checkHeadNodeConsistency(headNodes);
		return headNodes;
	}

	protected RuleHeadAnalysis(@NonNull MappingRegion mappingRegion) {
		super(mappingRegion);
	}

	private void addExtraHeads(@NonNull List<@NonNull Node> headNodes) {
		for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
			//			assert !node.isDependency();
			if (node.isDependency()) {
				node.setHead();
				assert !headNodes.contains(node);
				headNodes.add(node);
			}
		}
	}

	private void checkHeadNodeConsistency(@NonNull Iterable<@NonNull Node> headNodes) {
		Set<@NonNull Node> debugHeadNodes = new HashSet<>();
		for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
			if (node.isDependency() || node.isHead()) {
				debugHeadNodes.add(node);
			}
		}
		assert debugHeadNodes.equals(Sets.newHashSet(headNodes));
	}

	private @NonNull Iterable<@NonNull Node> computeHeadNodes(@NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSources, @Nullable List<@NonNull Node> preferredHeadNodes) {
		//
		//	Ripple the local target-from-sources to compute the overall target-from-sources closure.
		//
		Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSourcesClosure = CompilerUtil.computeClosure(targetFromSources);
		//
		//	Compute the inverse Set of all source nodes from which a particular target node can be reached by transitive to-one navigation.
		//
		Map<@NonNull Node, @NonNull Set<@NonNull Node>> sourceToTargetsClosure = CompilerUtil.computeInverseClosure(targetFromSourcesClosure);
		List<@NonNull HeadNodeGroup> headNodeGroups = computeHeadNodeGroups(targetFromSourcesClosure, sourceToTargetsClosure, preferredHeadNodes);
		if (RULE_HEAD_NODE_GROUPS.isActive()) {
			StringBuilder s = new StringBuilder();
			s.append(mappingRegion.getName());
			for (@NonNull HeadNodeGroup headNodeGroup : headNodeGroups) {
				s.append("\n\t");
				headNodeGroup.appendTo(s);
			}
			RULE_HEAD_NODE_GROUPS.println(s.toString());
		}
		List<@NonNull Node> headNodes = selectHeadNodes(headNodeGroups, preferredHeadNodes);
		//
		//	Add the pseudo-heads for true and dependency nodes.
		//
		addExtraHeads(headNodes);
		//
		//	Set/reset the head flag on each node.
		//
		setHeadNodes(targetFromSourcesClosure.keySet(), headNodes);
		return headNodes;
	}

	//
	//	Compute the Set of all source nodes from which each target can be reached by transitive to-one new navigation.
	//
	private @NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> computeNewTargetFromSources(@NonNull Iterable<@NonNull Node> realizedMiddleNodes) {
		Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSources = new HashMap<>();
		for (@NonNull Node targetNode : realizedMiddleNodes) {
			Set<@NonNull Node> sources = Sets.newHashSet(targetNode);
			targetFromSources.put(targetNode, sources);
			for (@NonNull Edge edge : QVTscheduleUtil.getIncomingEdges(targetNode)) {
				if (edge.isRealized() && edge.isNavigation()) {
					NavigationEdge navigationEdge = (NavigationEdge)edge;
					Node sourceNode = navigationEdge.getEdgeSource();
					sources.add(sourceNode);
				}
			}
		}
		return targetFromSources;
	}

	//
	//	Compute the Set of all source nodes from which each target can be reached by a direct to-one old navigation.
	//
	private @NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> computeOldTargetFromSources() {
		Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSources = new HashMap<>();
		for (@NonNull Node targetNode : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
			if (targetNode.isMatched() && !targetNode.isConstant() && !targetNode.isOperation()) {		// Operations are traversed by derived head group analysis
				if (targetNode.isLoaded() || targetNode.isChecked()) {
					Set<@NonNull Node> sources = Sets.newHashSet(targetNode);
					targetFromSources.put(targetNode, sources);
					for (@NonNull Edge edge : QVTscheduleUtil.getIncomingEdges(targetNode)) {
						if (edge instanceof NavigationEdge) {
							if (!edge.isRealized() && !((NavigationEdge)edge).isPartial()) {
								Node sourceNode = edge.getEdgeSource();
								if (sourceNode.isMatched() && !sourceNode.isConstant() && !sourceNode.isOperation()) {
									if (sourceNode.isLoaded() || sourceNode.isChecked()) {
										sources.add(sourceNode);
									}
								}
							}
						}
					}
				}
			}
		}
		return targetFromSources;
	}

	@Override
	protected @NonNull HeadNodeGroup createHeadNodeGroup(@NonNull List<@NonNull Node> headNodeGroup) {
		return new HeadNodeGroup(headNodeGroup)
		{
			@Override
			protected boolean canBeSameGroup(@NonNull Node sourceNode, @NonNull Edge source2targetEdge) {
				boolean isOldSource = sourceNode.isOld();
				return isOldSource ? source2targetEdge.isOld() : source2targetEdge.isNew();
			}

			@Override
			public String getName() {
				return headNodeGroup.get(0).getName();
			}
		};
	}

	private void setHeadNodes(@NonNull Set<@NonNull Node> reachableNodes, @NonNull List<@NonNull Node> headNodes) {
		for (@NonNull Node node : reachableNodes) {
			if (headNodes.contains(node)) {
				node.setHead();
			}
			else {
				node.resetHead();
			}
		}
	}
}