//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.search.ui.internal;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.xml.AbstractSAXParser;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.search.ui.SearchUIPlugin;
import org.eclipse.epf.search.ui.SearchUIResources;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.util.UmaUtil;
import org.xml.sax.Attributes;

/**
 * Performs a method search by iterating the current method library and parsing
 * the content element XMI files where necessary.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class MethodSearchOperation {

	private static final String SCAN_LIBRARY_TEXT = SearchUIResources.scanLibraryTask_name; 

	private static final String SCAN_ELEMENT_TEXT = SearchUIResources.scanElementTask_name; 

	private boolean debug;

	private MethodSearchInput searchInput;

	private ISearchResultCollector result;

	private String searchString;

	private boolean caseSensitive;

	private boolean regExp;

	private Pattern searchStringPattern;

	private Pattern elementNamePattern;

	private MethodElementScanner elementScanner;

	private List<String> parsedFiles = new ArrayList<String>();

	private IProgressMonitor progressMonitor;

	// Scans the content element XMI file associated with a Method element to
	// look for the search string.
	private class MethodElementScanner extends AbstractSAXParser {

		private MethodElement element;

		/**
		 * Creates a new instance.
		 */
		public MethodElementScanner() {
			super(null, false);
		}

		/**
		 * Parses the content XMI file associated with the given Method element.
		 * 
		 * @param element
		 *            a method element
		 */
		public void parse(MethodElement element) {
			this.element = element;
			String elementContentPath = getElementPath(element);
			String briefDescription = element.getBriefDescription();
			if (searchStringPattern.matcher(briefDescription).find()) {
				result.accept(element);
			}
			if (elementContentPath != null
					&& !parsedFiles.contains(elementContentPath)) {
				super.parse(elementContentPath);
				parsedFiles.add(elementContentPath);
			}
		}

		/**
		 * @see AbstractSAXParser#startElement(String, String, String,
		 *      Attributes)
		 */
		public void startElement(String namespaceURL, String localName,
				String qname, Attributes attributes) {
			for (int i = 0; i < attributes.getLength(); i++) {
				String name = attributes.getQName(i);
				if (!name.equals("briefDescription")) { //$NON-NLS-1$
					String value = attributes.getValue(i);
					if (searchStringPattern.matcher(value).find()) {
						result.accept(element);
					}
				}
			}
		}

		/**
		 * @see AbstractSAXParser#endElement(String, String, String)
		 */
		public void endElement(String namespaceURL, String localName,
				String qname) {
			String value = strBuf.toString();
			if (searchStringPattern.matcher(value).find()) {
				result.accept(element);
			}
			strBuf.setLength(0);
		}

	}

	/**
	 * Creates a new instance.
	 * 
	 * @param searchString
	 *            a search string
	 * @param namePattern
	 *            a name pattern
	 * @param result
	 *            a search result collector
	 */
	public MethodSearchOperation(MethodSearchInput searchInput,
			ISearchResultCollector result) {
		this.searchInput = searchInput;
		this.result = result;

		caseSensitive = searchInput.getCaseSensitive();
		regExp = searchInput.getRegularExpression();
		elementNamePattern = MethodSearchPattern.createPattern(searchInput
				.getNamePattern(), false, false);

		debug = SearchUIPlugin.getDefault().isDebugging();

		searchString = searchInput.getSearchString();
		if (searchString == null)
			searchString = ""; //$NON-NLS-1$
		if (searchString.length() > 0) {
			elementScanner = new MethodElementScanner();
			searchStringPattern = MethodSearchPattern.createPattern(
					searchString, caseSensitive, regExp);
		}

		if (debug) {
			System.out
					.println("MethodSearchOperation constructor: searchString=" //$NON-NLS-1$
							+ searchString
							+ ", elementNamePattern=" //$NON-NLS-1$
							+ searchInput.getNamePattern()
							+ ", caseSensitive=" + caseSensitive); //$NON-NLS-1$
		}
	}

	/**
	 * Executes the search operation.
	 * 
	 * @param progressMonitor
	 *            a progress monitor
	 */
	public void execute(IProgressMonitor progressMonitor) {
		this.progressMonitor = progressMonitor;
		this.progressMonitor.beginTask(SCAN_LIBRARY_TEXT, 7500);

		// Iterate the Method Library to look for elements that match the name
		// pattern.
		MethodLibrary library = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		List methodPlugins = LibraryUtil.getMethodPlugins(library);
		for (Iterator i = methodPlugins.iterator(); i.hasNext()
				&& !progressMonitor.isCanceled();) {
			MethodPlugin methodPlugin = (MethodPlugin) i.next();
			matchPattern(methodPlugin);

			MethodPackage methodPackage;
			if (searchInput.getSearchScope().includeCoreContent()) {
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.coreContentPath);
				searchMethodPackages(methodPackage);
			}

			if (searchInput.getSearchScope().include(
					MethodSearchScope.STANDARD_CATEGORY)) {
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.disciplineDefinitionPath);
				searchMethodPackages(methodPackage);
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.domainPath);
				searchMethodPackages(methodPackage);
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.workProductTypePath);
				searchMethodPackages(methodPackage);
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.roleSetPath);
				searchMethodPackages(methodPackage);
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.toolPath);
				searchMethodPackages(methodPackage);
			}

			if (searchInput.getSearchScope().include(
					MethodSearchScope.CUSTOM_CATEGORY)) {
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.customCategoryPath);
				searchMethodPackages(methodPackage);
			}

			if (searchInput.getSearchScope().include(
					MethodSearchScope.CAPABILITY_PATTERN)) {
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.capabilityPatternPath);
				searchMethodPackages(methodPackage);
			}

			if (searchInput.getSearchScope().include(
					MethodSearchScope.DELIVERY_PROCESS)) {
				methodPackage = UmaUtil.findMethodPackage(methodPlugin,
						ModelStructure.DEFAULT.deliveryProcessPath);
				searchMethodPackages(methodPackage);
			}
		}
	}

	/**
	 * Searches a Method Package.
	 * 
	 * @param methodPackage
	 *            a method package
	 */
	protected void searchMethodPackages(MethodPackage methodPackage) {
		if (methodPackage == null
				|| methodPackage.getName().equals(
						ModelStructure.HIDDEN_PACKAGE_NAME)) {
			return;
		}
		if (methodPackage instanceof ProcessComponent) {
			// Add the associated CapabilityPattern or DeliveryProcess to the
			// search result.
			ProcessComponent processComponent = (ProcessComponent) methodPackage;
			matchPattern(processComponent.getProcess());
		} else if (!isInternalProcessPackage(methodPackage)) {
			matchPattern(methodPackage);
		}

		List childPackages = methodPackage.getChildPackages();
		for (Iterator i = childPackages.iterator(); i.hasNext()
				&& !progressMonitor.isCanceled();) {
			searchMethodPackages((MethodPackage) i.next());
		}
		if (methodPackage instanceof ContentPackage) {
			ContentPackage contentPackage = (ContentPackage) methodPackage;
			List contentElements = contentPackage.getContentElements();
			for (Iterator j = contentElements.iterator(); j.hasNext()
					&& !progressMonitor.isCanceled();) {
				ContentElement contentElement = (ContentElement) j.next();
				matchPattern(contentElement);
				if (contentElement instanceof Artifact) {
					searchContainedArtifacts((Artifact) contentElement);
				} else if (contentElement instanceof Discipline) {
					searchSubDisciplines((Discipline) contentElement);
				} else if (contentElement instanceof Practice) {
					searchSubPractices((Practice) contentElement);
				} else if (contentElement instanceof Domain) {
					searchSubDomains((Domain) contentElement);
				}
			}
		} else if (methodPackage instanceof ProcessPackage) {
			ProcessPackage processPackage = (ProcessPackage) methodPackage;
			List processElements = processPackage.getProcessElements();
			for (Iterator j = processElements.iterator(); j.hasNext()
					&& !progressMonitor.isCanceled();) {
				ProcessElement processElement = (ProcessElement) j.next();
				if (!(processElement instanceof Activity)) {
					matchPattern(processElement);
				}
			}
		}
	}

	/**
	 * Returns <code>true</code> if the given package is an internal Process
	 * Package.
	 * 
	 * @param methodPackage
	 *            a method or process package
	 * @return <code>true</code> if the given package is an internal process
	 *         package
	 */
	protected boolean isInternalProcessPackage(MethodPackage methodPackage) {
		if (methodPackage instanceof ProcessPackage) {
			if (UmaUtil.getProcessComponent(methodPackage) != null) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Searches the contained artifacts of an artifact.
	 * 
	 * @param artifact
	 *            an artifact
	 */
	protected void searchContainedArtifacts(Artifact artifact) {
		if (artifact != null) {
			for (Iterator i = artifact.getContainedArtifacts().iterator(); i
					.hasNext()
					&& !progressMonitor.isCanceled();) {
				Artifact containedArtifact = (Artifact) i.next();
				matchPattern(containedArtifact);
				searchContainedArtifacts(containedArtifact);
			}
		}
	}

	/**
	 * Searches the sub disciplines of a discipline.
	 * 
	 * @param discipline
	 *            a discipline
	 */
	protected void searchSubDisciplines(Discipline discipline) {
		if (discipline != null) {
			for (Iterator i = discipline.getSubdiscipline().iterator(); i
					.hasNext()
					&& !progressMonitor.isCanceled();) {
				Discipline subDiscipline = (Discipline) i.next();
				matchPattern(subDiscipline);
				searchSubDisciplines(subDiscipline);
			}
		}
	}

	/**
	 * Searches the sub practices of a practice.
	 * 
	 * @param practice
	 *            a practice
	 */
	protected void searchSubPractices(Practice practice) {
		if (practice != null) {
			for (Iterator i = practice.getSubPractices().iterator(); i
					.hasNext()
					&& !progressMonitor.isCanceled();) {
				Practice subPractice = (Practice) i.next();
				matchPattern(subPractice);
				searchSubPractices(subPractice);
			}
		}
	}

	/**
	 * Searches the sub domains of a domain.
	 * 
	 * @param domain
	 *            a domain
	 */
	protected void searchSubDomains(Domain domain) {
		if (domain != null) {
			for (Iterator i = domain.getSubdomains().iterator(); i.hasNext()
					&& !progressMonitor.isCanceled();) {
				Domain subDomain = (Domain) i.next();
				matchPattern(subDomain);
				searchSubDomains(subDomain);
			}
		}
	}

	/**
	 * Adds the given method element to the search result collection if its name
	 * or presentation name matches the name pattern.
	 * 
	 * @param element
	 *            a method element
	 */
	protected void matchPattern(MethodElement element) {
		try {
			if (searchInput.getSearchScope().include(element)) {
				String name = element.getName();
				String taskName = MessageFormat.format(SCAN_ELEMENT_TEXT,
						new Object[] { name });
				progressMonitor.setTaskName(taskName);
				boolean foundMatch = false;
				if (element instanceof DescribableElement) {
					String presentationName = ((DescribableElement) element)
							.getPresentationName();
					foundMatch = (name != null && elementNamePattern.matcher(
							name).matches())
							|| (presentationName != null && elementNamePattern
									.matcher(presentationName).matches());
				} else {
					foundMatch = (name != null && elementNamePattern.matcher(
							name).matches());
				}
				if (foundMatch) {
					if (searchString.length() == 0) {
						result.accept(element);
					} else {
						try {
							elementScanner.parse(element);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
				progressMonitor.worked(1);
			}
		} catch (Exception e) {
			SearchUIPlugin.getDefault().getLogger().logError(e);
		}
	}

	/**
	 * Returns the path of the content XML file associated with a method
	 * element.
	 */
	protected String getElementPath(MethodElement element) {
		Resource resource = null;
		if (element instanceof DescribableElement) {
			DescribableElement describableElement = (DescribableElement) element;
			ContentDescription contentDescription = describableElement
					.getPresentation();
			if (contentDescription == null) {
				return null;
			}
			resource = contentDescription.eResource();
		} else {
			resource = element.eResource();
		}
		if (resource != null) {
			URI resourceURI = resource.getURI();
			if (resourceURI != null) {
				return resourceURI.toFileString();
			}
		}
		return null;
	}

}