/*******************************************************************************
 * Copyright (c) 2007, 2009 Chase Technology Ltd - http://www.chasetechnology.co.uk
 * 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:
 *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
 *     David Carver (STAR) -  bug 243577 - Added retrieving all called-templates.
 *     David Carver (STAR) -  bug 246503 - Handled nested circular includes.
 *******************************************************************************/
package org.eclipse.wst.xsl.core.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import org.eclipse.core.resources.IFile;
import org.eclipse.wst.xsl.core.XSLCore;
import org.eclipse.wst.xsl.core.internal.util.Debug;

/**
 * The composed stylesheet, consisting of all templates and variables available
 * via imports and includes.
 * 
 * <p>
 * The <code>fix()</code> method does the actual work of populating the fields
 * of this, so it must be called before calling any of the other methods.
 * </p>
 * 
 * <p>
 * Note that this model may not be valid - for instance there may be more than
 * one named template for a given name or more than one global variable with a
 * given name.
 * </p>
 * 
 * @author Doug Satchwell
 * @since 1.0
 */
public class StylesheetModel extends XSLModelObject {
	private final Stylesheet stylesheet;
	boolean circularReference;
	final Set<IFile> files = new HashSet<IFile>();
	final Set<Stylesheet> stylesheets = new HashSet<Stylesheet>();
	final List<Include> includeModel = new ArrayList<Include>();
	final List<Import> importModel = new ArrayList<Import>();
	final Set<Template> templateSet = new HashSet<Template>();
	final List<Template> templates = new ArrayList<Template>();
	final List<Variable> globalVariables = new ArrayList<Variable>();
	final List<CallTemplate> callTemplates = new ArrayList<CallTemplate>();
	final List<Function> functions = new ArrayList<Function>();

	/**
	 * Create a new instance of this.
	 * 
	 * @param stylesheet
	 *            the stylesheet that this is the model for
	 */
	public StylesheetModel(Stylesheet stylesheet) {
		this.stylesheet = stylesheet;
	}

	/**
	 * Get all stylesheets that are included in this stylesheet anywhere in the
	 * hierarchy via either import or include.
	 * 
	 * @return the set of stylesheets in the entire hierarchy
	 */
	public List<Include> getIncludes() {
		return includeModel;
	}

	/**
	 * Get all files that are included in this stylesheet anywhere in the
	 * hierarchy via either import or include.
	 * 
	 * @return the set of files in the entire hierarchy
	 */
	public Set<IFile> getFileDependencies() {
		return files;
	}

	/**
	 * Get the stylesheet that this is the model for.
	 * 
	 * @return the stylesheet that this is the model for
	 */
	public Stylesheet getStylesheet() {
		return this.stylesheet;
	}

	/**
	 * Get all global variables that are included in this stylesheet anywhere in
	 * the hierarchy via either import or include.
	 * 
	 * @return the set of files in the entire hierarchy
	 */
	public List<Variable> getGlobalVariables() {
		return globalVariables;
	}

	/**
	 * Get all templates that are included in this stylesheet anywhere in the
	 * hierarchy via either import or include.
	 * 
	 * @return the set of templates in the entire hierarchy
	 */
	public List<Template> getTemplates() {
		return templates;
	}

	/**
	 * A utility method that traverses all stylesheet in the hierarchy of
	 * stylesheets (not including the current stylesheet), and adds all their
	 * templates to the returned list. Therefore the returned list has no regard
	 * for whether a template is 'visible' (i.e. whether it might be overridden
	 * since it was included via an import). The order of the templates in the
	 * list is arbitrary.
	 * 
	 * @return an unordered list of all templates from all stylesheets.
	 */
	public List<Template> findAllNestedTemplates() {
		List<Template> allTemplates = new ArrayList<Template>();
		for (Stylesheet stylesheet : stylesheets) {
			allTemplates.addAll(stylesheet.getTemplates());
		}
		return allTemplates;
	}

	/**
	 * Get all named templates that are included in this stylesheet anywhere in
	 * the hierarchy via either import or include which have the given name.
	 * 
	 * @param name
	 *            the template name
	 * @return the set of named templates with the given name
	 */
	public List<Template> getTemplatesByName(String name) {
		List<Template> matching = new ArrayList<Template>(templates.size());
		for (Template template : templates) {
			if (name.equals(template.getName()))
				matching.add(template);
		}
		return matching;
	}

	/**
	 * Get all templates that match the given template (determined from
	 * <code>Template.equals()</code>).
	 * 
	 * @param toMatch
	 *            the template to match
	 * @return the set of templates that match
	 */
	public List<Template> findMatching(Template toMatch) {
		List<Template> matching = new ArrayList<Template>(templates.size());
		for (Template template : templates) {
			if (template.equals(toMatch))
				matching.add(template);
		}
		return matching;
	}

	/**
	 * Get whether this has a circular reference anywhere in its import/included
	 * hierarchy.
	 * 
	 * @return <code>true</code> if this has a circular reference
	 */
	public boolean hasCircularReference() {
		return circularReference;
	}

	/**
	 * Perform the process of traversing the hierarchy to determine all of the
	 * properties of this. Note that this method may force other
	 * <code>StylesheetModel</code>'s to be built during the process of fixing.
	 */
	public void fix() {
		long start = System.currentTimeMillis();

		if (Debug.debugXSLModel) {
			System.out.println("Fixing " + stylesheet.getFile() + "..."); //$NON-NLS-1$ //$NON-NLS-2$
		}
		templates.addAll(stylesheet.getTemplates());
		templateSet.addAll(stylesheet.getTemplates());
		globalVariables.addAll(stylesheet.globalVariables);
		callTemplates.addAll(stylesheet.getCalledTemplates());
		functions.addAll(stylesheet.getFunctions());
		for (Include inc : stylesheet.getIncludes()) {
			handleInclude(inc);
		}
		for (Import inc : stylesheet.getImports()) {
			handleInclude(inc);
		}
		circularReference = checkCycles();
		if (Debug.debugXSLModel) {
			long end = System.currentTimeMillis();
			System.out
					.println("FIX " + stylesheet.getFile() + " in " + (end - start) + "ms"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	private boolean checkCycles() {
		Set<IFile> seen = new HashSet<IFile>();
		IFile mainFile = getStylesheet().getFile();
		if (checkCycles(mainFile, seen)) return true;

		// For the remaining files, assume 
		seen.add(mainFile);
		for (IFile file : files) {
			if (file.equals(mainFile)) continue;
			if (checkCycles(file, seen)) return true;
		}
		return false;
	}
	
	public static boolean checkCycles(IFile included, Set<IFile> seen) {
		if (seen.contains(included)) return true;
		seen.add(included);
		
		StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
				included);

		for (Include inc : includedModel.getIncludes()) {
			IFile includedFile = inc.getHrefAsFile();
			if (checkCycles(includedFile, seen)) return true;
		}

		seen.remove(included);
		return false;
	}
	
	private void handleInclude(Include include) {
		IFile file = include.getHrefAsFile();

		if (file == null || !file.exists()) {
			return;
		}

		files.add(file);

		StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
				file);
		if (includedModel == null)
			return;
		stylesheets.add(includedModel.getStylesheet());
		globalVariables.addAll(includedModel.globalVariables);
		callTemplates.addAll(includedModel.getCallTemplates());
		if (include.getIncludeType() == Include.INCLUDE) {
			includeModel.add(include);
			templates.addAll(includedModel.getTemplates());
			templateSet.addAll(includedModel.getTemplates());
		} else {
			importModel.add((Import) include);
			for (Template includedTemplate : includedModel.getTemplates()) {
				if (!templateSet.contains(includedTemplate)) {
					templates.add(includedTemplate);
					templateSet.add(includedTemplate);
				}
			}
		}
	}

	@Override
	public Type getModelType() {
		return Type.STYLESHEET_MODEL;
	}

	public List<CallTemplate> getCallTemplates() {
		return callTemplates;
	}

	/**
	 * Get a List of all functions that are known.
	 * @return 
	 * @since 1.1
	 */
	public List<Function> getFunctions() {
		return functions;
	}

	/**
	 * Get all functions that are included in this stylesheet anywhere in the
	 * hierarchy via either import or include which have the given name.
	 * 
	 * @param name
	 *            the template name
	 * @return the set of named templates with the given name
	 * @since 1.1
	 */
	public List<Function> getFunctionByName(String name) {
		List<Function> matching = new ArrayList<Function>(functions.size());
		for (Function function : functions) {
			if (name.equals(function.getName()))
				matching.add(function);
		}
		return matching;
	}

}