/*******************************************************************************
 * Copyright (c) 2006, 2010 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060131   121071 rsinha@ca.ibm.com - Rupam Kuehner (initial creation)
 * 20060426   138051 kathy@ca.ibm.com - Kathy Chan
 * 20060427   126780 rsinha@ca.ibm.com - Rupam Kuehner
 * 20080923   247525 mahutch@ca.ibm.com - Mark Hutchinson, cache not updated properly when project facet versions changed
 * 20100811   322429 mahutch@ca.ibm.com - Mark Hutchinson, Improve performance of launching the Web Services Wizard
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.wsrt;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.ws.internal.consumption.common.FacetMatcher;
import org.eclipse.jst.ws.internal.consumption.common.FacetSetsByTemplateCache;
import org.eclipse.jst.ws.internal.consumption.common.FacetUtils;
import org.eclipse.jst.ws.internal.consumption.common.RequiredFacetVersion;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;

/**
 * FacetMatchCache caches results of calculations made respecting
 * the suitability of projects and project types for serviceRuntimes
 * and clientRuntimes.
 * 
 * <br/><br/>
 * Terminology used in the javadoc in this class:
 * <ul>
 * <li><b>serviceRuntime</b>: extension to org.eclipse.jst.ws.consumption.ui.serviceRuntimes.
 * The Java representation of this is org.eclipse.jst.ws.internal.consumption.ui.wsrt.ServiceRuntimeDescriptor</li>
 * <li><b>clientRuntime</b>: extension to org.eclipse.jst.ws.consumption.ui.clientRuntimes.
 * The Java representation of this is org.eclipse.jst.ws.internal.consumption.ui.wsrt.ClientRuntimeDescriptor</li>
 * </ul>
 *
 */
public class FacetMatchCache implements IResourceChangeListener
{
  //single instance per workbench
  private static FacetMatchCache instance_;
  
  
  //Tables related to existing projects in the workspace
  
  //serviceFacetMatchTable_: 
  //key: Object of type String.
  //     Forward slash separated concatenation of a serviceRuntimeId and a projectName 
  //     (e.g. org.eclipse.jst.ws.axis.creation.java/wp).
  //value: Object of type org.eclipse.jst.ws.internal.consumption.common.FacetMatcher.
  //       The FacetMatcher contains the matching characteristics calculated for the 
  //       serviceRuntime and project in the key.
  private Hashtable serviceFacetMatchTable_;
  
  //serviceTableKeysByProjectName_: 
  //key: Object of type String.
  //     project name (e.g. wp)
  //value: Set of elements of type String. The Strings in the Set are keys from the serviceFacetMatchTable_ 
  //       that contain the project name (e.g. org.eclipse.jst.ws.axis.creation.java/wp). Used to rapidly
  //       delete entries from serviceFacetMatchTable_ after a project is deleted from the workspace.
  private Hashtable serviceTableKeysByProjectName_;
  
  //clientFacetMatchTable_;
  //key: Object of type String.
  //     forward slash separated concatenation of a clientRuntimeId and a projectName 
  //     (e.g. org.eclipse.jst.ws.axis.consumption.java/wp)
  //value: Object of type org.eclipse.jst.ws.internal.consumption.common.FacetMatcher
  //       The FacetMatcher contains the matching characteristics calculated for the 
  //       clientRuntime and project in the key.
  private Hashtable clientFacetMatchTable_;
  
  //clientTableKeysByProjectName_
  //key: Object of type String.
  //     project name (e.g. wp)
  //value: Set of elements of type String. The Strings in the Set are keys from the clientFacetMatchTable_ 
  //       that contain the project name (e.g. org.eclipse.jst.ws.axis.consumption.java/wp). Used to rapidly
  //       delete entries from clientFacetMatchTable_ after a project is deleted from the workspace.
  private Hashtable clientTableKeysByProjectName_;
  
  //projectEntriesToDelete_: elements of type String containing the names of projects that have
  //been deleted from the workspace but their corresponding entries from serviceFacetMatchTable_ 
  //and clientFacetMatchTable_ have yet to be deleted.
  private List projectEntriesToDelete_;
    
  
  
  //Tables related to templates  
  
  //templatesByServiceRuntimeId_:
  //key: Object of type String.
  //     serviceRuntime id
  //value: Set of elements of type org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate   
  //       This the set of templates that support the serviceRuntime identified by the key.
  private Hashtable templatesByServiceRuntimeId_;
  
  //templatesByClientRuntimeId_
  //key: Object of type String.
  //     clientRuntime id
  //value: Set of elements of type org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate
  //       This the set of templates that support the clientRuntime identified by the key.
  private Hashtable templatesByClientRuntimeId_;
  
  
  /**
   * Returns a singleton instance of this class.
   * 
   * @return A singleton FacetMatchCache object.
   */
  public static synchronized FacetMatchCache getInstance()
  {
    if (instance_ == null)
    {
      instance_ = new FacetMatchCache();
      instance_.load();
    }
    return instance_;
  }  
  
  private void load()
  {
    serviceFacetMatchTable_ = new Hashtable();
    serviceTableKeysByProjectName_ = new Hashtable();
    clientFacetMatchTable_ = new Hashtable();    
    clientTableKeysByProjectName_ = new Hashtable();
    projectEntriesToDelete_ = new ArrayList();
    templatesByClientRuntimeId_ = new Hashtable();
    templatesByServiceRuntimeId_ = new Hashtable();
    
    //Listen for deletions of projects in order to delete all entries in
    //Hashtables for the deleted project.
    ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_DELETE);
  }
  

  /*
   * Returns the FacetMatcher resulting from matching a serviceRuntime or clientRuntime with an existing project.
   * @param isClient true if runtimeId is a clientRuntimeId. false if runtimeId is a serviceRuntimeId.
   * @param runtimeId the id of a clientRuntime if isClient is true or the id of a serviceRuntime if
   * isClient is false.
   * @param projectName the name of an existing project.
   * 
   * @returns FacetMatcher resulting from calling FacetUtils.match(..) using the serviceRuntime or clientRuntime id
   * and the project name. Returns null if the project doesn't exist. Non-faceted existing projects will always result
   * in a FacetMatcher with isMatch() equal to false (with the exception of Java projects which are a special case 
   * - see FacetUtils.getFacetsForProject()).
   */
  public synchronized FacetMatcher getMatchForProject(boolean isClient, String runtimeId, String projectName)
  {    
    //Delete entries from tables if there are deletions pending.
    if (projectEntriesToDelete_.size() > 0)
    {
      Iterator projectItr = projectEntriesToDelete_.iterator();
      while(projectItr.hasNext())
      {
        String projectNameToDelete = (String)projectItr.next();
       
        //Delete entries from client table
        removeTableEntriesForProject(true, projectNameToDelete);
        
        //Delete entries from service table
        removeTableEntriesForProject(false, projectNameToDelete);
      }
      
      //Clear the projectEntriesToDelete list
      projectEntriesToDelete_.clear();
    }
    
    IProject project = ProjectUtilities.getProject(projectName);
    FacetMatcher fm = null;
    if (project != null && project.exists())
    {
      String key = getKey(runtimeId, projectName);
      if (isClient)
      {
        fm = (FacetMatcher) clientFacetMatchTable_.get(key);
      }
      else
      {
        fm = (FacetMatcher) serviceFacetMatchTable_.get(key);
      }
      
      if (fm == null)
      {
        // This combination has not yet been calculated and cached so calculate it and cache it.        
        fm = calculateFacetMatcher(isClient, runtimeId, projectName);         
        if (isClient)
        {
          clientFacetMatchTable_.put(key,fm);     
        }
        else
        {
          serviceFacetMatchTable_.put(key, fm);
        }
        updateTableOfKeys(isClient, key, projectName);
        
      } else
      {
        // If the project's facets have changed since the last time the
        // facets were calculated, refresh the facetMatcher.        
        Set currentFacetVersions = FacetUtils.getFacetsForProject(projectName);
        Set previousFacetVersions = fm.getFacetsTested();
        if (!currentFacetVersions.equals(previousFacetVersions))
        {
          //recalculate and cache the FacetMatcher
          fm = calculateFacetMatcher(isClient, runtimeId, projectName);
          if (isClient)
          {
            clientFacetMatchTable_.put(key,fm);         
          }
          else
          {
            serviceFacetMatchTable_.put(key, fm);
          }                    
        }
      }
    }
    
    return fm;    
  }
  
  /**
   * Updates serviceTableKeysByProjectName_ or clientTableKeysByProjectName_ with
   * the provided project name and key. This is called whenever a new entry is 
   * added to serviceFacetMatchTable_ or clientFacetMatchTable_.
   * @param isClient true if runtimeId is a clientRuntimeId. false if runtimeId is a serviceRuntimeId.
   * @param key 
   * @param projectName
   */
  private void updateTableOfKeys(boolean isClient, String key, String projectName)
  {
    Set setOfKeysForProjectName = null;
    if (isClient)
    {
      setOfKeysForProjectName = (Set)clientTableKeysByProjectName_.get(projectName);      
    }
    else
    {
      setOfKeysForProjectName = (Set)serviceTableKeysByProjectName_.get(projectName);
    }
    
    if (setOfKeysForProjectName == null)
    {
      //Add an entry in the table for this project.
      Set keys = new HashSet();
      keys.add(key);
      if (isClient)
      {
        clientTableKeysByProjectName_.put(projectName, keys);
      }
      else
      {
        serviceTableKeysByProjectName_.put(projectName, keys);
      }
    }
    else
    {
      //Update the entry in the table for this project.
      setOfKeysForProjectName.add(key);      
    }
  }
  
  /**
   * Returns the {@link FacetMatcher} calculated for the given serviceRuntime or clientRuntime and project
   * @param isClient true if runtimeId is a clientRuntimeId. false if runtimeId is a serviceRuntimeId.
   * @param runtimeId the id of a clientRuntime if isClient is true or the id of a serviceRuntime if
   * isClient is false.
   * @param projectName the name of an existing project.
   * @return FacetMatcher resulting from calling FacetUtils.match(..) using the serviceRuntime or clientRuntime id
   * and the project name. Returns null if the project doesn't exist. Non-faceted existing projects will always result
   * in a FacetMatcher with isMatch() equal to false (with the exception of Java projects which are a special case 
   * - see FacetUtils.getFacetsForProject()).
   */
  private FacetMatcher calculateFacetMatcher(boolean isClient, String runtimeId, String projectName)
  {
    FacetMatcher fm = null;
    RequiredFacetVersion[] rfvs = null;
    if (isClient)
    {
      ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(runtimeId);
      rfvs = desc.getRequiredFacetVersions();
    }
    else
    {
      ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(runtimeId);
      rfvs = desc.getRequiredFacetVersions();
    }
    
    Set facetVersions = new HashSet(FacetUtils.getFacetsForProject(projectName));
    if (facetVersions == null)
    {
      fm = new FacetMatcher();
      fm.setMatch(false);
      return fm;
    }    
    
    fm = FacetUtils.match(rfvs, facetVersions);
    
    // Check if the facet runtime required by the required facet is supported
    // by the project without chaning it's current facet runtime
    
    IRuntime fProjectRuntime = FacetUtils.getFacetRuntimeForProject(projectName);
    if (fProjectRuntime != null) {
    	String fProjectRuntimeName = fProjectRuntime.getName();
    	boolean projectSupportRequiredFacetRuntime = false;
    	Set rts = FacetUtils.getRuntimes(rfvs);
    	for (Iterator iterator = rts.iterator(); iterator.hasNext() && !projectSupportRequiredFacetRuntime;) {
    		IRuntime fRequiredRuntime = (IRuntime) iterator.next();
    		if (fRequiredRuntime != null) {
    			if (fRequiredRuntime.getName().equals(fProjectRuntimeName)) {
    				projectSupportRequiredFacetRuntime = true;
    			}
    		}
    	}

    	// if project does not support the required facet runtime, set FacetMatch match to false
    	if (!projectSupportRequiredFacetRuntime) {
    		fm.setMatch(false);
    	}
    }
    return fm;
  }

  private String getKey(String a, String b)
  {
    StringBuffer keysb = new StringBuffer();
    keysb.append(a);
    keysb.append("/");
    keysb.append(b);    
    return keysb.toString();    
  }  
  
  /**
   * Removes all table entries in this cache for the given project
   * @param isClient true to remove entries from client side tables. false to remove entries from service side tables
   * @param projectName
   */
  private void removeTableEntriesForProject(boolean isClient, String projectName)
  {
    //First remove the entries from clientFacetMatchTable_ or serviceFacetMatchTable_
    //that have keys containing this project name.
    Set setOfKeysForProjectName = null;
    if (isClient)
    {
      setOfKeysForProjectName = (Set)clientTableKeysByProjectName_.get(projectName);      
    }
    else
    {
      setOfKeysForProjectName = (Set)serviceTableKeysByProjectName_.get(projectName);
    }
    
    if (setOfKeysForProjectName != null)
    { 
      Iterator keysItr = setOfKeysForProjectName.iterator();
      while (keysItr.hasNext())
      {
        String key = (String)keysItr.next();
        if (isClient)
        { 
          clientFacetMatchTable_.remove(key);          
        }
        else
        {
          serviceFacetMatchTable_.remove(key);
        }
      }
      
      //Second, remove the entry in clientTableKeysByProjectName_ or serviceTableKeysByProjectName_
      //with this projectName as the key.
      if (isClient)
      {
        clientTableKeysByProjectName_.remove(projectName);  
      }
      else
      {
        serviceTableKeysByProjectName_.remove(projectName);
      }
      
    }
    
  }

  /**
   * Returns a set of templates supported by the given clientRuntime
   * @param clientRuntimeId id of a clientRuntime
   * @returns Set (elementtype: IFacetedProjectTemplate)
   */
  public synchronized Set getTemplatesForClientRuntime(String clientRuntimeId)
  {
    Set templates = (Set)templatesByClientRuntimeId_.get(clientRuntimeId);
    if (templates != null)
    {
      //Return the cached set of templates.
      return templates;
    }
    else
    {
      //Calculate the templates, cache them for later use, and return them.
      ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(clientRuntimeId);
      
      Set validTemplates = null;
      Set<String> suitableIds = desc.getSuitableProjectTemplates();
      if (!suitableIds.isEmpty()) {
    	  //If a list of suitable project templates is specified in the metadata, then use those project templates and do not search
    	  validTemplates = new HashSet(1);
    	  for (String s : suitableIds) {
    		  IFacetedProjectTemplate t = ProjectFacetsManager.getTemplate(s);
    		  if (t != null)
    			  validTemplates.add(t);
    	  }
      }
      
      //if the set of valid templates is still empty, then search for valid templates based on required facet versions
      if (validTemplates == null || validTemplates.isEmpty()) {
    	  validTemplates = getTemplates(desc.getRequiredFacetVersions(), desc.getUnsuitableProjectTemplates());
      }
       
      templatesByClientRuntimeId_.put(clientRuntimeId, validTemplates);
      return validTemplates;
    }
  }
  
  /**
   * Returns a set of templates supported by the given serviceRuntime
   * @param serviceRuntimeId id of a serviceRuntime
   * @returns Set (elementtype: IFacetedProjectTemplate)
   */  
  public synchronized Set getTemplatesForServiceRuntime(String serviceRuntimeId)
  {
    Set templates = (Set)templatesByServiceRuntimeId_.get(serviceRuntimeId);
    if (templates != null)
    {
      //Return the cached set of templates.
      return templates;
    }
    else
    {
      //Calculate the templates, cache them for later use, and return them.
      ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(serviceRuntimeId);
      Set validTemplates = null;
      Set<String> suitableIds = desc.getSuitableProjectTemplates();
      if (!suitableIds.isEmpty()) {
    	  //If a list of suitable project templates is specified in the metadata, then use those project templates and do not search
    	  validTemplates = new HashSet(1);
    	  for (String s : suitableIds) {
    		  IFacetedProjectTemplate t = ProjectFacetsManager.getTemplate(s);
    		  if (t != null)
    			  validTemplates.add(t);
    	  }
      }
      
      //if the set of valid templates is still empty, then search for valid templates based on required facet versions
      if (validTemplates == null || validTemplates.isEmpty()) {
    	  validTemplates = getTemplates(desc.getRequiredFacetVersions(), desc.getUnsuitableProjectTemplates());
      }
      
      templatesByServiceRuntimeId_.put(serviceRuntimeId, validTemplates);
      return validTemplates;
    }
  }
 
   /**
   * Returns the set of templates that supported the given required facet versions.
   * @param requiredFacetVersions
   * @param unSuitableTemplates set of unsuitable template ids to exclude from the search for increased performance
   * @return Set containing elemets of type {@link IFacetedProjectTemplate}.
   */
  private Set getTemplates(RequiredFacetVersion[] requiredFacetVersions, Set<String> unSuitableTemplates)  {
    Set templates = new HashSet();
    for( Iterator itr = ProjectFacetsManager.getTemplates().iterator(); itr.hasNext(); ) {    	
        final IFacetedProjectTemplate template = (IFacetedProjectTemplate) itr.next();
        String templateId = template.getId();
        if (unSuitableTemplates == null || !unSuitableTemplates.contains(templateId)) { //if we know the template is unsuitable, then exclude it        	
	        if (templateId.indexOf("ear") == -1 && templateId.indexOf("wst.web") == -1) { //Don't include the EARs!!
	          Set[] combinations = FacetSetsByTemplateCache.getInstance().getFacetVersionCombinationsFromTemplate(templateId);
	          
	          for (int i=0; i<combinations.length; i++) {
	            FacetMatcher fm = FacetUtils.match(requiredFacetVersions, combinations[i]);
	            if (fm.isMatch()) {
	              //Found a combination that worked. Add the template to the list and move on.
	              templates.add(template);
	              break;
	            }
	          }
	        }
        }
    }
    return templates;
  }
  
  public synchronized void resourceChanged(IResourceChangeEvent event)
  {
    if (event.getType() == IResourceChangeEvent.PRE_DELETE)
    {
      IResource projectResource = event.getResource();
      if (projectResource!=null)
      {
        String projectName = projectResource.getName();
        
        //Add this project name to the list of project entries
        //to delete. Next time getMatchForProject is called all
        //entries for this project from all tables in this cache 
        //will be deleted.
        projectEntriesToDelete_.add(projectName);
      }
    }    
  }  
}
