/*******************************************************************************
 * Copyright (c) 2004, 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 API and implementation
 *******************************************************************************/

package org.eclipse.wst.xml.core.internal.search;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.common.core.search.SearchMatch;
import org.eclipse.wst.common.core.search.SearchParticipant;
import org.eclipse.wst.common.core.search.SearchRequestor;
import org.eclipse.wst.common.core.search.document.ComponentDeclarationEntry;
import org.eclipse.wst.common.core.search.document.Entry;
import org.eclipse.wst.common.core.search.document.FileReferenceEntry;
import org.eclipse.wst.common.core.search.document.SearchDocument;
import org.eclipse.wst.common.core.search.document.SearchDocumentSet;
import org.eclipse.wst.common.core.search.pattern.ComponentSearchPattern;
import org.eclipse.wst.common.core.search.pattern.FileReferencePattern;
import org.eclipse.wst.common.core.search.pattern.SearchPattern;
import org.eclipse.wst.common.core.search.scope.ContentTypeSearchScope;
import org.eclipse.wst.common.core.search.scope.SearchScope;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.search.impl.IXMLSearchConstants;
import org.eclipse.wst.xml.core.internal.search.impl.XMLSearchDocument;
import org.eclipse.wst.xml.core.internal.search.matching.PatternMatcher;
import org.eclipse.wst.xml.core.internal.search.matching.XMLSearchPatternMatcher;
import org.eclipse.wst.xml.core.internal.search.quickscan.XMLQuickScan;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 */
public abstract class XMLSearchParticipant extends SearchParticipant {
	
	protected static final boolean debugPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.xml.core.internal.search/perf")); //$NON-NLS-1$ //$NON-NLS-2$

	public XMLSearchParticipant() {
		super();
	}

	
	/*
 public  boolean initialize(SearchPattern pattern, String[] contentTypes){
		
	    super.initialize(pattern, contentTypes);
		this.supportedContentTypes = contentTypes;
		
		if(pattern instanceof XMLComponentSearchPattern){
			return true;
		}
		return false;
	}*/

	

	public SearchDocument createSearchDocument(String documentPath) {

		return new XMLSearchDocument(documentPath, this);

	}

	public String getDescription() {
		return "XML search participant"; //$NON-NLS-1$
	}



	private void locateMatches(SearchPattern pattern, SearchDocument document,
			SearchRequestor requestor, Map searchOptions, IProgressMonitor monitor) {

        // TODO... utilize search options (that should get passed down via the SearchEngine)
        // to specify if accurate source coordinates are req'd if not, simply use the SAX results
        //
        if (pattern.getMatchRule() == SearchPattern.R_PATTERN_MATCH)
        {          
          IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(document.getPath()));
          // TODO.. don't assume the category is COMPONENT_DECL... handle any arbitarty category
          Entry[] entries = document.getEntries(IXMLSearchConstants.COMPONENT_DECL, null, 0);
          for (int i = 0; i < entries.length; i++)
          {
            // TODO.. don't assume this is just a component declaration entry            
            ComponentDeclarationEntry entry = (ComponentDeclarationEntry)entries[i];
            SearchMatch searchMatch = new SearchMatch(null, 0, 0, file);
            searchMatch.map.put("name", entry.getName());
            searchMatch.map.put("metaName", entry.getMetaName());
            try
            {
              requestor.acceptSearchMatch(searchMatch);
            }
            catch (Exception e)
            {              
            }
          }  
        }
        else 
        {  if (document.getModel() instanceof IDOMModel) {
			IDOMModel domModel = (IDOMModel) document.getModel();
			IDOMElement contextNode = (IDOMElement) domModel.getDocument()
					.getDocumentElement();
			DOMVisitor visitor = new DOMVisitor(document.getPath(), pattern,
					requestor);
			visitor.visit(contextNode);
		}
        }
	}
	
	private PatternMatcher getAdapter(Object adaptableObject, Class adapterType) {
		if (PatternMatcher.class.equals(adapterType) &&
				(adaptableObject instanceof XMLSearchPattern ||
				adaptableObject instanceof XMLComponentSearchPattern) ) {
			return new XMLSearchPatternMatcher();
		} 
		return null; 
	}

	private class DOMVisitor {

		String path;
		SearchPattern pattern;
		SearchRequestor requestor;
		PatternMatcher matcher;

		
		protected DOMVisitor(String path, SearchPattern pattern,
				SearchRequestor requestor) {
			super();
			this.path = path;
			this.pattern = pattern;
			
			matcher = (PatternMatcher)pattern.getAdapter(PatternMatcher.class);
			if(matcher == null){
				matcher = getAdapter(pattern, PatternMatcher.class);
			}
			this.requestor = requestor;
		}

		private void visit(Node node) {
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				match((Element)node);
				NodeList nodeList = node.getChildNodes();
				for (int i = 0; i < nodeList.getLength(); i++) {
					Node aNode = nodeList.item(i);
					visit(aNode);
				}
			}
		}

		private void match(Element node) {
			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
					new Path(path));
			if(matcher != null){
				matcher.locateMatches(pattern, file, node, requestor);
			}

			
		}

	}

	public SearchScope selectDocumentLocations(SearchPattern pattern, SearchScope scope, Map searchOptions, IProgressMonitor monitor) {
		/*
		 * gate #1: reduce the scope to the files with the content type that
		 * could be searched using this participant
		 */ 
		String[] contentTypes = getSupportedContentTypes();	
		if(contentTypes != null && contentTypes.length > 0){
			scope = new ContentTypeSearchScope(scope, contentTypes);
		}
		return super.selectDocumentLocations(pattern, scope, searchOptions, monitor);
	}
	
	public abstract ComponentSearchContributor getSearchContributor();


	public void beginSearching(SearchPattern pattern, Map searchOptions) {
		
		super.beginSearching(pattern, searchOptions);
		if(pattern instanceof XMLComponentDeclarationPattern){
			XMLComponentDeclarationPattern componentPattern = (XMLComponentDeclarationPattern)pattern;
			XMLSearchPattern childPattern = getSearchContributor().getDeclarationPattern(componentPattern.getMetaName());
			if(childPattern != null){
					childPattern.setSearchName(componentPattern.getName().getLocalName());
					childPattern.setSearchNamespace(componentPattern.getName().getNamespace());
	     			componentPattern.setChildren(new XMLSearchPattern[]{childPattern});
			}
			
		}
		else if(pattern instanceof XMLComponentReferencePattern){
			XMLComponentReferencePattern componentPattern = (XMLComponentReferencePattern)pattern;
			XMLSearchPattern[] childPatterns = getSearchContributor().getReferencesPatterns(componentPattern.getMetaName());
			for (int i = 0; i < childPatterns.length; i++) {
				XMLSearchPattern childPattern = childPatterns[i];
				childPattern.setSearchName(componentPattern.getName().getLocalName());
				childPattern.setSearchNamespace(componentPattern.getName().getNamespace());				
			}
			componentPattern.setChildren(childPatterns);
			
		}
	}
	
	
	/**
	 * The intend of this method is to limit the search to the files that have content 
	 * which can be searched for the given pattern. It is called from 
	 * {@link #selectDocumentLocations(SearchPattern, SearchScope, IProgressMonitor)}
	 * 
	 * @param pattern the search pattern that is searched for
	 * @return content type's unique identifiers that could be searched for the given pattern.
	 */
	public abstract String[] getSupportedContentTypes();

	public void populateSearchDocument(SearchDocument document, SearchPattern pattern)
	{
		PatternMatcher matcher = (PatternMatcher)pattern.getAdapter(PatternMatcher.class);
		if(matcher == null){
			matcher = getAdapter(pattern, PatternMatcher.class);
		}
		XMLQuickScan.populateSearchDocument(document, matcher, pattern);		
	}

	public void locateMatches(SearchDocumentSet documentSet, SearchPattern pattern, SearchScope scope, SearchRequestor requestor, Map searchOptions, IProgressMonitor monitor) throws CoreException
	{
		long time = System.currentTimeMillis();
		
		// TODO: use the file reference entries in the documents to reduce the scope to the referenced files only
		// SearchDocument[] documents = documentSet.getSearchDocuments(id);
                
        // check to see if the search pattern is qualified by a file location
        // if this is the case then we can use file scoping rules to prune the matches
        IFile targetFile = null;
        if (pattern instanceof ComponentSearchPattern)
        {
          ComponentSearchPattern componentSearchPattern = (ComponentSearchPattern)pattern;
          targetFile = componentSearchPattern.getFile();                                       
        }		
        
		// here we should have in scope only referenced files
		IFile[] files = scope.enclosingFiles();  
		for (int i = 0; i < files.length; i++)
		{
			IFile file = files[i];
			String path = file.getLocation().toString();
			SearchDocument document = documentSet.getSearchDocument(path, id); 
			if (document != null)
			{	
			Entry[] entries = document.getEntries(getSearchEntryCategory(pattern), null, 0);           
			if(entries != null && entries.length > 0)
            {
              //for (int j = 0; j < entries.length; j++)
              //{
              //  Entry entry = entries[j];
                //System.out.println("entry " + entry.getCategory() + " " + entry.getKey() + " " + entry.getClass().getName());                 
              //}  
              
              boolean isInScope = true;
              if (targetFile != null)
              {
                try
                {
                  isInScope = isLinked(documentSet, "file:///" + path, "file:///" + targetFile.getLocation().toString());
                  //if (path.endsWith("CancelSelection.wsdl")  && path.indexOf("clone1") != -1)
                  //{
                  //  fileReferenceTable.debug(qualifiedPath, 0, 5);
                  //}                   
                }
                catch (Exception e)
                {
                  e.printStackTrace();
                }
              }              
              if (isInScope)
              { 
			    this.locateMatches(pattern, document, requestor, searchOptions, monitor);
              }  
            }
			}
		}
		
		
		if (debugPerf)
		{
			System.out
					.println(""
							+ getDescription()
							+ ": " + (System.currentTimeMillis() - time) + "ms for locateMatches"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		
	}
    
    private boolean isLinked(SearchDocumentSet set, String source, String target)
    {
      return isLinked(set, source, target, new HashMap());
    }
    
    private boolean isLinked(SearchDocumentSet set, String source, String target, HashMap visited)
    {
      if (source.equals(target))
        return true;
      
      String fileProtocol = "file:///";            
      if (source.startsWith(fileProtocol))
      {    
        
      SearchDocument document = set._tempGetSearchDocumetn(source.substring(fileProtocol.length()));      
      if (document != null)
      {        
        URIResolver uriResolver = URIResolverPlugin.createResolver();        
        Entry[] entries = document.getEntries(IXMLSearchConstants.REF, null, 0);
        String[] resolveEntry = new String[entries.length];        
        for (int j = 0; j < entries.length; j++)
        {
          Entry entry = entries[j];
          if (entry instanceof FileReferenceEntry)
          {
            FileReferenceEntry fileReferenceEntry = (FileReferenceEntry)entry;
            // TODO.. record an utilize the public id from the fileReferenceEntry
            //
            if (fileReferenceEntry.getRelativeFilePath() != null)
            {  
              String resolvedURI = uriResolver.resolve(source, null, fileReferenceEntry.getRelativeFilePath());
              resolveEntry[j] = resolvedURI;
              if (resolvedURI.equals(target))
              {
                return true;
              }             
            }  
          }
        }
        // now see if there's an indirect link from the source to the target
        // we keep track of the nodes we've already visited to avoid cycles
        if (visited.get(source) == null)
        {
          visited.put(source, Boolean.TRUE);
          for (int j = 0; j < entries.length; j++)
          {                     
            String resolvedURI = resolveEntry[j];
            if (resolvedURI != null && isLinked(set, resolveEntry[j], target, visited))                
              return true;            
          }    
        }                      
      }            
      } 
      return false;
    }
    
   
    
	public static String getSearchEntryCategory(SearchPattern pattern){
		if(pattern instanceof XMLComponentDeclarationPattern){
			return IXMLSearchConstants.COMPONENT_DECL;
		}
		else if(pattern instanceof XMLComponentReferencePattern){
			return IXMLSearchConstants.COMPONENT_REF;
		}
		else if(pattern instanceof FileReferencePattern){
		   return IXMLSearchConstants.COMPONENT_REF;
		}
		return null;
	}   
}
