/*******************************************************************************
 * Copyright (c) 2006, 2016 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 API and implementation
 *******************************************************************************/
package org.eclipse.help.internal.toc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.help.ICriteria;
import org.eclipse.help.ITocContribution;
import org.eclipse.help.IUAElement;
import org.eclipse.help.internal.Anchor;
import org.eclipse.help.internal.HelpPlugin;
import org.eclipse.help.internal.Topic;
import org.eclipse.help.internal.UAElement;
import org.eclipse.help.internal.criteria.CriteriaProviderRegistry;
import org.eclipse.help.internal.dynamic.DocumentProcessor;
import org.eclipse.help.internal.dynamic.DocumentReader;
import org.eclipse.help.internal.dynamic.ExtensionHandler;
import org.eclipse.help.internal.dynamic.IncludeHandler;
import org.eclipse.help.internal.dynamic.ProcessorHandler;
import org.eclipse.help.internal.dynamic.ValidationHandler;

/*
 * Assembles toc contributions (toc fragments) into complete, linked, and
 * assembled books.
 */
public class TocAssembler {

	private DocumentProcessor processor;
	private ProcessorHandler[] handlers;

	private Map<String, Set<String>> anchorsByContributionId;
	private List<TocContribution> contributions;
	private Map<String, TocContribution> contributionsById;
	private Map<String, ITocContribution[]> contributionsByLinkTo;
	private Set<ITocContribution> processedContributions;
	private Map<String, String[]> requiredAttributes;
	private Set<String> tocsToFilter;


	public TocAssembler() {
		this.tocsToFilter = new HashSet<>();
	}

	public TocAssembler(Set<String> tocsToFilter) {
		this.tocsToFilter = tocsToFilter;
	}

	/*
	 * Assembles the given toc contributions into complete, linked
	 * books. The originals are not modified.
	 */
	public List<TocContribution> assemble(List<TocContribution> contributions) {
		this.contributions = contributions;
		anchorsByContributionId = null;
		contributionsById = null;
		contributionsByLinkTo = null;
		processedContributions = null;

		List<TocContribution> books = getBooks();
		Iterator<TocContribution> iter = books.iterator();
		while (iter.hasNext()) {
			TocContribution book = iter.next();
			process(book);
		}
		return books;
	}

	/*
	 * Returns the list of contributions that should appear as root TOCs
	 * (books). Contributions are books if the following conditions are
	 * true:
	 *
	 * 1. isPrimary() returns true.
	 * 2. The toc has no "link_to" attribute defined (does not link into
	 *    another toc), or the link_to target anchor doesn't exist.
	 * 3. No other toc has a link to this contribution (via "link" element).
	 */
	private List<TocContribution> getBooks() {
		Map<String, String> linkedContributionIds = getLinkedContributionIds(contributions);
		List<TocContribution> books = new ArrayList<>();
		Iterator<TocContribution> iter = contributions.iterator();
		while (iter.hasNext()) {
			TocContribution contrib = iter.next();
			boolean isValidLinkTo = hasValidLinkTo(contrib);
			boolean isLinkedId = linkedContributionIds.containsKey(contrib.getId());
			if (!isValidLinkTo && !isLinkedId) {
				if (contrib.isPrimary()) {
				    books.add(contrib);
				    if (HelpPlugin.DEBUG_TOC) {
						String msg = "Primary Toc Found: " + contrib.getId(); //$NON-NLS-1$
						String linkTo = contrib.getLinkTo();
						if (linkTo != null) {
							msg += " - cannot find link to: "; //$NON-NLS-1$
							msg += linkTo;
						}
					    System.out.println(msg);
					}
				} else {
					if (HelpPlugin.DEBUG_TOC) {
						String msg = "Table of contents is not primary and not linked to another TOC " + contrib.getId() + " (skipping)"; //$NON-NLS-1$ //$NON-NLS-2$
						System.out.println(msg);
					}
				}
			} else {
				contrib.setSubToc(true);
				if (HelpPlugin.DEBUG_TOC) {
					String msg = "Toc " + contrib.getId();  //$NON-NLS-1$
					if (isValidLinkTo) {
						msg += " has a valid link to " + contrib.getLinkTo(); //$NON-NLS-1$
					}
					if (isLinkedId) {
						msg += " is linked from " + linkedContributionIds.get(contrib.getId()); //$NON-NLS-1$
					}
					System.out.println(msg);
				}
			}
		}
		return books;
	}

	/*
	 * Returns the set of ids of contributions that are linked to by other
	 * contributions, i.e. at least one other contribution has a link element
	 * pointing to it.
	 */
	private Map<String, String> getLinkedContributionIds(List<TocContribution> contributions) {
		if (processor == null) {
			processor = new DocumentProcessor();
		}
		final Map<String, String> linkedContributionIds = new HashMap<>();
		ProcessorHandler[] linkFinder = new ProcessorHandler[] {
			new ValidationHandler(getRequiredAttributes()),
			new ProcessorHandler() {
				@Override
				public short handle(UAElement element, String id) {
					if (element instanceof Link) {
						Link link = (Link)element;
						String toc = link.getToc();
						if (toc != null) {
							TocContribution srcContribution = getContribution(id);
							linkedContributionIds.put(HrefUtil.normalizeHref(srcContribution.getContributorId(), toc), id);
						}
					}
					return UNHANDLED;
				}
			}
		};
		processor.setHandlers(linkFinder);
		ListIterator<TocContribution> iter = contributions.listIterator();
		while (iter.hasNext()) {
			TocContribution contrib = iter.next();
			try {
				String id = contrib.getId();
				if (!tocsToFilter.contains(id)) {
				    processor.process((Toc)contrib.getToc(), id);
				}
			}
			catch (Throwable t) {
				iter.remove();
				String msg = "Error processing help table of contents: " + contrib.getId() + " (skipping)"; //$NON-NLS-1$ //$NON-NLS-2$
				HelpPlugin.logError(msg, t);
			}
		}
		return linkedContributionIds;
	}

	/*
	 * Checks whether the toc contribution with the given id contains the
	 * given anchor.
	 */
	private boolean hasAnchor(String tocContributionId, String anchorId) {
		TocContribution contrib = getContribution(tocContributionId);
		if (contrib != null) {
			process(contrib);
			if (anchorsByContributionId != null) {
				Set<String> anchors = anchorsByContributionId.get(tocContributionId);
				if (anchors != null) {
					return anchors.contains(anchorId);
				}
			}
		}
		// invalid contribution, or no anchors
		return false;
	}

	/*
	 * Checks whether the given contribution has a link_to defined, and it
	 * is valid (contribution and anchor exist).
	 */
	private boolean hasValidLinkTo(TocContribution contrib) {
		String linkTo = contrib.getLinkTo();
		if (linkTo != null) {
			String normalized = HrefUtil.normalizeHref(contrib.getContributorId(), linkTo);
			int index = normalized.indexOf('#');
			if (index != -1) {
				String id = normalized.substring(0, index);
				String anchorId = normalized.substring(index + 1);
				return hasAnchor(id, anchorId);
			}
		}
		return false;
	}

	/*
	 * Processes the given contribution, if it hasn't been processed yet. This
	 * performs the following operations:
	 *
	 * 1. Topic hrefs are normalized, e.g. "path/doc.html" ->
	 *    "/my.plugin/path/doc.html"
	 * 2. Links are resolved, link is replaced with target content, extra docs
	 *    are merged.
	 * 3. Anchor contributions are resolved, tocs with link_to's are inserted
	 *    at anchors and extra docs merged.
	 */
	private void process(ITocContribution contribution) {
		if (processedContributions == null) {
			processedContributions = new HashSet<>();
		}
		// don't process the same one twice
		if (!processedContributions.contains(contribution)) {
			if (processor == null) {
				processor = new DocumentProcessor();
			}
			if (handlers == null) {
				DocumentReader reader = new DocumentReader();
				handlers = new ProcessorHandler[] {
					new NormalizeHandler(),
					new LinkHandler(),
					new AnchorHandler(),
					new IncludeHandler(reader, contribution.getLocale()),
					new ExtensionHandler(reader, contribution.getLocale()),
				};
			}
			processor.setHandlers(handlers);
			processor.process((Toc)contribution.getToc(), contribution.getId());
			processedContributions.add(contribution);
		}
	}

	/*
	 * Returns the contribution with the given id.
	 */
	private TocContribution getContribution(String id) {
		if (contributionsById == null) {
			contributionsById = new HashMap<>();
			Iterator<TocContribution> iter = contributions.iterator();
			while (iter.hasNext()) {
				TocContribution contribution = iter.next();
				contributionsById.put(contribution.getId(), contribution);
			}
		}
		return contributionsById.get(id);
	}

	/*
	 * Returns all contributions that define a link_to attribute pointing to
	 * the given anchor path. The path has the form "<contributionId>#<anchorId>",
	 * e.g. "/my.plugin/toc.xml#myAnchor".
	 */
	private ITocContribution[] getAnchorContributions(String anchorPath) {
		if (contributionsByLinkTo == null) {
			contributionsByLinkTo = new HashMap<>();
			Iterator<TocContribution> iter = contributions.iterator();
			while (iter.hasNext()) {
				TocContribution srcContribution = iter.next();
				String linkTo = srcContribution.getLinkTo();
				if (linkTo != null) {
					String destAnchorPath = HrefUtil.normalizeHref(srcContribution.getContributorId(), linkTo);
					ITocContribution[] array = contributionsByLinkTo.get(destAnchorPath);
					if (array == null) {
						array = new TocContribution[] { srcContribution };
					}
					else {
						// If a contribution of this id is already included don't include a second time
						boolean isAlreadyIncluded = false;
						for (int i = 0; i < array.length; i++) {
							if (srcContribution.getId().equals(array[i].getId())) {
								isAlreadyIncluded = true;
							}
						}
						if (!isAlreadyIncluded) {
							TocContribution[] temp = new TocContribution[array.length + 1];
							System.arraycopy(array, 0, temp, 0, array.length);
							temp[array.length] = srcContribution;
							array = temp;
						}
					}
					contributionsByLinkTo.put(destAnchorPath, array);
				}
			}
		}
		ITocContribution[] contributions = contributionsByLinkTo.get(anchorPath);
		if (contributions == null) {
			contributions = new TocContribution[0];
		}
		return contributions;
	}

	private Map<String, String[]> getRequiredAttributes() {
		if (requiredAttributes == null) {
			requiredAttributes = new HashMap<>();
			requiredAttributes.put(Toc.NAME, new String[] { Toc.ATTRIBUTE_LABEL });
			requiredAttributes.put(Topic.NAME, new String[] { Topic.ATTRIBUTE_LABEL });
			requiredAttributes.put("anchor", new String[] { "id" }); //$NON-NLS-1$ //$NON-NLS-2$
			requiredAttributes.put("include", new String[] { "path" }); //$NON-NLS-1$ //$NON-NLS-2$
			requiredAttributes.put("link", new String[] { "toc" }); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return requiredAttributes;
	}

	/*
	 * Adds the given extra documents to the contribution.
	 */
	private void addExtraDocuments(TocContribution contribution, String[] extraDocuments) {
		if (extraDocuments.length > 0) {
			String[] destExtraDocuments = contribution.getExtraDocuments();
			String[] combinedExtraDocuments;
			if (destExtraDocuments.length == 0) {
				combinedExtraDocuments = extraDocuments;
			}
			else {
				Set<String> set = new HashSet<>();
				set.addAll(Arrays.asList(destExtraDocuments));
				set.addAll(Arrays.asList(extraDocuments));
				combinedExtraDocuments = set.toArray(new String[set.size()]);
			}
			contribution.setExtraDocuments(combinedExtraDocuments);
		}
	}

	/*
	 * Handler that resolves link elements (replaces the link element with
	 * the linked-to toc's children.
	 */
	private class LinkHandler extends ProcessorHandler {
		@Override
		public short handle(UAElement element, String id) {
			if (element instanceof Link) {
				Link link = (Link)element;
				UAElement parent = link.getParentElement();
				if (parent != null) {
					String toc = link.getToc();
					if (toc != null) {
						TocContribution destContribution = getContribution(id);
						TocContribution srcContribution = getContribution(HrefUtil.normalizeHref(destContribution.getContributorId(), toc));
						if (srcContribution != null) {
							process(srcContribution);
							IUAElement[] children = srcContribution.getToc().getChildren();
							for (int i=0;i<children.length;++i) {
								parent.insertBefore((UAElement)children[i], link);
							}
							addExtraDocuments(destContribution, srcContribution.getExtraDocuments());
						}
						parent.removeChild(link);
					}
				}
				return HANDLED_SKIP;
			}
			return UNHANDLED;
		}
	}

	/*
	 * Handles anchor contributions. If any contribution's toc wants to link
	 * into this one at the current anchor, link it in.
	 */
	private class AnchorHandler extends ProcessorHandler {
		@Override
		public short handle(UAElement element, String id) {
			if (element instanceof Anchor) {
				if (tocsToFilter.contains(id)) {
					return UNHANDLED;
			    }
				Anchor anchor = (Anchor)element;
				UAElement parent = anchor.getParentElement();
				if (parent != null) {
					String anchorId = anchor.getId();
					if (anchorId != null) {
						// add to set of known anchors
						if (anchorsByContributionId == null) {
							anchorsByContributionId = new HashMap<>();
						}
						Set<String> set = anchorsByContributionId.get(id);
						if (set == null) {
							set = new HashSet<>();
							anchorsByContributionId.put(id, set);
						}
						set.add(anchorId);

						// process contributions
						TocContribution destContribution = getContribution(id);
						if (destContribution != null) {
							ITocContribution[] srcContributions = getAnchorContributions(
									destContribution.getId() + '#' + anchorId);
							for (int i=0;i<srcContributions.length;++i) {
								process(srcContributions[i]);
								IUAElement[] children = srcContributions[i].getToc().getChildren();
								for (int j=0;j<children.length;++j) {
									parent.insertBefore((UAElement)children[j], anchor);
								}
								addExtraDocuments(destContribution, srcContributions[i].getExtraDocuments());
							}
						}
					}
				}
			}
			// allow the extension handler to act on anchors afterwards
			return UNHANDLED;
		}
	}

	/*
	 * Normalizes topic hrefs, by prepending the plug-in id to form an href.
	 * e.g. "path/myfile.html" -> "/my.plugin/path/myfile.html"
	 */
	private class NormalizeHandler extends ProcessorHandler {
		@Override
		public short handle(UAElement element, String id) {
			if (element instanceof Topic) {
				Topic topic = (Topic)element;
				String href = topic.getHref();
				if (href != null) {
					topic.setHref(normalize(href, id));
				}

				processCriteria(element, id);

				return HANDLED_CONTINUE;
			}
			else if (element instanceof Toc) {
				Toc toc = (Toc)element;
				toc.setHref(id);
				String topic = toc.getTopic();
				if (topic != null) {
					toc.setTopic(normalize(topic, id));
				}

				processCriteria(element, id);

				return HANDLED_CONTINUE;
			}
			return UNHANDLED;
		}

		private String normalize(String href, String id) {
			ITocContribution contribution = getContribution(id);
			if (contribution != null) {
				String pluginId = contribution.getContributorId();
				return HrefUtil.normalizeHref(pluginId, href);
			}
			else {
				int index = id.indexOf('/', 1);
				if (index != -1) {
					String pluginId = id.substring(1, index);
					return HrefUtil.normalizeHref(pluginId, href);
				}
			}
			return href;
		}

		private void processCriteria(UAElement element, String id) {
			if(HelpPlugin.getCriteriaManager().isCriteriaEnabled()){
				ITocContribution contribution = getContribution(id);
				String locale = contribution.getLocale();
				ICriteria[] criteria = new ICriteria[0];
				if (element instanceof Topic) {
					Topic topic = (Topic) element;
					criteria = CriteriaProviderRegistry.getInstance().getAllCriteria(topic);
				}
				else if (element instanceof Toc) {
					Toc toc = (Toc) element;
					criteria = CriteriaProviderRegistry.getInstance().getAllCriteria(toc);
				}

				HelpPlugin.getCriteriaManager().addCriteriaValues(criteria, locale);
			}
		}
	}
}
