//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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.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; //$NON-NLS-1$

	private static final String SCAN_ELEMENT_TEXT = SearchUIResources.scanElementTask_name; //$NON-NLS-1$

	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 parsedFiles = new ArrayList();

	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 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 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 String[] { 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;
	}

}