/*******************************************************************************
 * Copyright (c) 2002, 2005 Object Factory Inc.
 * 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:
 *		Object Factory Inc. - Initial implementation
 *******************************************************************************/
package org.eclipse.ant.internal.ui.dtd.schema;

import com.ibm.icu.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.ant.internal.ui.dtd.ParseError;
import org.eclipse.ant.internal.ui.dtd.util.SortedMap;
import org.eclipse.ant.internal.ui.dtd.util.SortedMapFactory;

/**
 * NfmParser parses an NFA and returns an equivalent DFA if it can do so in
 * linear time and space (in terms of the original NFA).<p>
 * 
 * As used here, NfmParser is called lazily when someone actually asks for a
 * Dfm. This is for performance reasons. Why go to the work of calculating all
 * those Dfms if nobody ever uses them?
 * 
 * Well-formed errors in content models have already been detected. The only
 * error that can arise in NfmParser is an ambiguity error.
 * 
 * Bruggemann-Klein showed that if an NFA is 1-unambiguous, an epsilon-free NFA
 * constructed from it in linear time is actually a DFA. This is obvious
 * in NfmParser. The algorithm works by removing all ambiguous transitions as
 * the graph is constructed, then proving that the reduced graph is equivalent
 * to the original in time linear in the number of ambiguous transitions.
 * 
 * An effort is made to keep the DFA small, but there is no optimization
 * step, as DFAs are small anyway, with some linear inflation around *.
 * In a pathological case, like the classical (a*,a*,a*,..., a*) the number
 * of transitions in the DFA can be quadratic but this algorithm will not blow
 * up exponentially.
 * 
 * @author Bob Foster
 */
public class NfmParser {
	
	public Dfm parse(Nfm nfm) throws ParseError {
		
		// Parse nfm into dfm
		
		Dfm dfm = parseStart(nfm.getStart(), nfm.getStop());
		
		// Make list of dfms in graph
		
		ArrayList dfms = new ArrayList();
		collect(dfm, dfms);
		
		// Detect accept conflicts
		
		HashMap duplicates = new HashMap();
		detect(dfms, duplicates);
		
		// Replace duplicate dfms in graph
		
		replace(dfms, duplicates);
		
		// Allow nfm memory to be re-used
		
		Nfm.free(nfm);
		NfmNode.freeAll();
		
		return dfm;
	}
	
	private void reportError(String name) throws ParseError {
		throw new ParseError(MessageFormat.format(AntDTDSchemaMessages.NfmParser_Ambiguous, new String[]{name}));
	}

	public static void collect(Dfm dfm, List dfms) {
		dfms.add(dfm);
		collect1(dfm, dfms);
	}
	
	private static void collect1(Dfm dfm, List dfms) {
		Object[] follows = dfm.getValues();
		if (follows != null) {
			for (int i = 0; i < follows.length; i++) {
				Dfm follow = (Dfm) follows[i];
				if (!dfms.contains(follow)) {
					dfms.add(follow);
					collect1(follow, dfms);
				}
			}
		}
	}


	/**
	 * Replace duplicate dfms found during conflict resolution.
	 */
	private void replace(ArrayList dfms, HashMap removed) {
		for (int i = 0; i < dfms.size(); i++) {
			Dfm dfm = (Dfm) dfms.get(i);
			Object[] follows = dfm.getValues();
			if (follows != null) {
				for (int j = 0; j < follows.length; j++) {
					Dfm replacement, follow = (Dfm) follows[j];
					while ((replacement = (Dfm) removed.get(follow)) != null)
						follow = replacement;
					follows[j] = follow;
				}
			}
		}
		
		// release dfms so can be re-used
		Iterator rit = removed.keySet().iterator();
		while (rit.hasNext())
			Dfm.free((Dfm)rit.next());
	}


	/**
	 * Detect conflicts in each state. Two transitions are a potential conflict
	 * if they accept the same string value. They are an actual conflict if
	 * their follow dfms are not identical and they are an actual ambiguity if
	 * the transition atoms of the follow dfms are not pairwise identical.
	 * This is derived from the rule of Bruggemann-Klein, which determines
	 * that (a|a)b is not ambiguous, but both (a,b)|(a,c) and (a,b)|(a,b) are.
	 * The latter might be surprising, but that's committee work for you.
	 * If two transitions are not ambiguous, one can be removed without
	 * affecting the language accepted, and thus we have converted our
	 * epsilon-free NFA into a DFA. If any two transitions are ambiguous,
	 * we report an error and our responsibility ends. Note that no transitions
	 * can be removed until all have been checked; this might disguise the
	 * ambiguity in, e.g., ((a|a),b,(a|a))*.
	 */
	private void detect(ArrayList dfms, HashMap duplicates) throws ParseError {
		for (Iterator iter = dfms.iterator(); iter.hasNext();) {
			Dfm dfm = (Dfm) iter.next();
			
			Object[] accepts = dfm.getKeys();
			Object[] follows = dfm.getValues();
			if (accepts != null) {
				String last = null;
				for (int i = 0, lasti = -1; i < accepts.length; i++) {
					String accept = accepts[i].toString();
					// accepts strings are interned allowing identity comparison
					
					if (last != null && last == accept) {
						if (follows[i] != follows[lasti])
							checkConflict(new Conflict(accept, (Dfm)follows[lasti], (Dfm)follows[i]));
					}
					else {
						last = accept;
						lasti = i;
					}
				}
			}
		}
		
		// once more for removal
		
		for (Iterator iter = dfms.iterator(); iter.hasNext();) {
			Dfm dfm = (Dfm) iter.next();
			
			// record conflicts
			Object[] accepts = dfm.getKeys();
			Object[] follows = dfm.getValues();
			boolean remove = false;
			if (accepts != null) {
				boolean[] removes = new boolean[accepts.length];
				String last = null;
				for (int i = 0, lasti = -1; i < accepts.length; i++) {
					String accept = accepts[i].toString();
					
					if (last != null && last == accept) {
						remove = true;
						removes[i] = true;
						if (follows[i] != follows[lasti]) {
							Dfm dfmhi = (Dfm) follows[i];
							Dfm dfmlo = (Dfm) follows[lasti];
							if (dfmhi.id < dfmlo.id) {
								Dfm tmp = dfmhi;
								dfmhi = dfmlo;
								dfmlo = tmp;
							}
							Dfm dup = (Dfm) duplicates.get(dfmhi);
							if (dup == null || dfmlo.id < dup.id) {
								duplicates.put(dfmhi, dfmlo);
							} else {
								duplicates.put(dfmlo, dup);
							}
						}
					}
					else {
						last = accept;
						lasti = i;
					}
				}
			
				if (remove) {
					SortedMap map = dfm.getMap();
					int i = 0;
					for (Iterator iterator = map.keyIterator(); iterator.hasNext(); i++) {
						iterator.next();
						if (removes[i])
							iterator.remove();
					}
					SortedMapFactory.freeMap(map);
				}
			}
		}
	}
	
	/**
	 * Check conflict and report ambiguity.
	 * @param conflict Potential ambiguity
	 */
	private void checkConflict(Conflict conflict) throws ParseError {
		if (conflict.dfm1.accepting != conflict.dfm2.accepting) {
			reportError(conflict.name);
		}
		Object[] accept1 = conflict.dfm1.getKeys();
		Object[] accept2 = conflict.dfm2.getKeys();
		if ((accept1 == null) != (accept2 == null)) {
			reportError(conflict.name);
		}
		if (accept1 != null) {
			if (accept1.length != accept2.length) {
				reportError(conflict.name);
			}
			for (int j = 0; j < accept2.length; j++) {
				if (accept1[j] != accept2[j]) {
					reportError(conflict.name);
				}
			}
		}
	}

	/**
	 * Recursive parse that visits every node reachable from
	 * the start symbol.
	 */
	private Dfm parseStart(NfmNode start, NfmNode accept) {
		// mark the start node
		Dfm result = Dfm.dfm(false);
		start.dfm = result;

		// we can minimize alias dfms by marking all starting transfer links
		while (start.next1 != null && start.next2 == null && start.symbol == null) {
			start = start.next1;
			start.dfm = result;
		}
		
		Dfm parsed = parse(1, start, accept);
		result.merge(parsed);
		
		Dfm.free(parsed);
		
		return result;
	}
	
	private void parseNext(int mark, Dfm result, NfmNode start, NfmNode accept) {
		Dfm parsed = parse(mark+1, start, accept);
		result.merge(parsed);
		
		Dfm.free(parsed);
	}
	
	/**
	 * Recursive parse that visits every node reachable from
	 * the start symbol.
	 */
	private Dfm parse(int mark, NfmNode start, NfmNode accept) {
		
		// eliminate useless recursion (note that accept node has no branches)
		while (start.next1 != null && start.next2 == null && start.symbol == null)
			start = start.next1;
			
		// if we reached the accept node, return an empty dfm that accepts
		if (start == accept)
			return Dfm.dfm(true);
		
		// for a symbol, construct a dfm that accepts the symbol
		if (start.symbol != null) {
			Dfm nextdfm = null;
			NfmNode next = start.next1, snext = next;
			while (snext.dfm == null && snext.next1 != null && snext.next2 == null && snext.symbol == null)
				snext = snext.next1;
			if (snext.dfm != null) {
				for (NfmNode n = next; n != snext; n = n.next1)
					n.dfm = snext.dfm;
				nextdfm = snext.dfm;
			}
			else {
				nextdfm = Dfm.dfm(false);
				snext.dfm = nextdfm;
				for (NfmNode n = next; n != snext; n = n.next1)
					n.dfm = nextdfm;
				parseNext(mark, nextdfm, snext, accept);
			}
			Dfm dfm = Dfm.dfm(start.symbol, nextdfm);
			return dfm;
		}
		
		// otherwise, follow both branches and return the combined result
		Dfm dfm1 = null, dfm2 = null;
		int saveMark;
		if (start.next1 != null && start.next1.mark != mark) {
			saveMark = start.next1.mark;
			start.next1.mark = mark;
			dfm1 = parse(mark, start.next1, accept);
			start.next1.mark = saveMark;
		}
		if (start.next2 != null && start.next2.mark != mark) {
			saveMark = start.next2.mark;
			start.next2.mark = mark;
			dfm2 = parse(mark, start.next2, accept);
			start.next2.mark = saveMark;
		}
			
		if (dfm2 != null) {
			if (dfm1 != null)
				dfm1.merge(dfm2);
			else
				dfm1 = dfm2;
		}
		return dfm1;
	}

	private static class Conflict {
		public String name;
		public Dfm dfm1, dfm2;
		public Conflict(String name, Dfm dfm1, Dfm dfm2) {
			this.name = name;
			this.dfm1 = dfm1;
			this.dfm2 = dfm2;
		}
		public int hashCode() {
			return dfm1.hashCode() + dfm2.hashCode();
		}
		public boolean equals(Object o) {
			if (o == this)
				return true;
			if (!(o instanceof Conflict))
				return false;
			Conflict other = (Conflict) o;
			return (dfm1 == other.dfm1 && dfm2 == other.dfm2)
				|| (dfm1 == other.dfm2 && dfm2 == other.dfm1);
		}
	}
	
}
