/*******************************************************************************
 * Copyright (c) 2005, 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     
 * 20060204 124408   rsinha@ca.ibm.com - Rupam Kuehner      
 * 20060217 126757   rsinha@ca.ibm.com - Rupam Kuehner
 * 20060221 119111   rsinha@ca.ibm.com - Rupam Kuehner
 * 20060427 126780   rsinha@ca.ibm.com - Rupam Kuehner
 * 20060517 126965   kathy@ca.ibm.com - Kathy Chan
 * 20060905   156230 kathy@ca.ibm.com - Kathy Chan, Handling projects with no target runtime
 * 20070505   184772 kathy@ca.ibm.com - Kathy Chan
 * 20080305   220371 kathy@ca.ibm.com - Kathy Chan
 * 20080305   220371 kathy@ca.ibm.com - Kathy Chan - reverting previous change to 220371
 * 20080326   220371 kathy@ca.ibm.com - Kathy Chan - re-applying 220371
 * 20081001   243869 ericdp@ca.ibm.com - Eric D. Peters, Web Service tools allowing mixed J2EE levels
 * 20091123   242615 mahutch@ca.ibm.com - Mark Hutchinson, Use project creation operations to create projects
 * 20100211   302631 mahutch@ca.ibm.com - Mark Hutchinson, NullPointerException creating utility projects via CreateFacetedProjectCommand
 *******************************************************************************/

package org.eclipse.jst.ws.internal.consumption.command.common;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.applicationclient.internal.creation.AppClientFacetProjectCreationDataModelProvider;
import org.eclipse.jst.j2ee.internal.ejb.project.operations.EjbFacetProjectCreationDataModelProvider;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.web.archive.operations.WebFacetProjectCreationDataModelProvider;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetProjectCreationDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.UtilityProjectCreationDataModelProvider;
import org.eclipse.jst.server.core.FacetUtil;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ServerUtils;
import org.eclipse.jst.ws.internal.consumption.ConsumptionMessages;
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.osgi.util.NLS;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetDataModelProperties;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetProjectCreationDataModelProperties;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetProjectCreationDataModelProperties.FacetDataModelMap;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerType;
import org.eclipse.wst.server.core.ServerCore;

public class CreateFacetedProjectCommand extends AbstractDataModelOperation
{

  //name of the project to be created
  private String   projectName; 

  //name of the EAR project associated with projectName
  private String   earProjectName; 

  //id of the IFacetedProjectTemplate to be used to create this project.
  private String   templateId;
  
  //required facet versions that must be satisfied when creating the project (this comes from
  //the selected serverRuntime or clientRuntime in the calling scenario)
  private RequiredFacetVersion[]   requiredFacetVersions;

  //server type id - used to determine the facet runtime the created project will be bound to
  //if serverInstanceId is null or empty
  private String   serverFactoryId;

  //server id - used to determine the facet runtime the created project will be bound to. May
  //be null or empty.
  private String   serverInstanceId;
  
  //facet runtime determined from the serverInstanceId or serverFactoryId
  private org.eclipse.wst.common.project.facet.core.runtime.IRuntime facetRuntime;
  
  
  private boolean containsWebFacet(Set facetVersions) {
	  for (Iterator iter = facetVersions.iterator(); iter.hasNext();) {
		  IProjectFacetVersion requiredFacetVersion = (IProjectFacetVersion) iter.next();
		  if (requiredFacetVersion.getProjectFacet().getId().equals(IModuleConstants.JST_WEB_MODULE)) {
			  return true;
		  }
	  }
	  return false;
  }
  
  //return the project creation data model for the templateId or null if no data model found
  private IDataModel getDataModelForTemplate(Set requiredFixedFacets) {
	  IDataModel dm = null;	  
	  if (templateId == null) 
		  return null;
	  else if (templateId.equals(IJ2EEModuleConstants.JST_EJB_TEMPLATE)) {
		  dm = DataModelFactory.createDataModel(new EjbFacetProjectCreationDataModelProvider());  
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, projectName);
		  dm.setBooleanProperty(IJ2EEFacetProjectCreationDataModelProperties.ADD_TO_EAR, false);
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_RUNTIME, facetRuntime);
	  }
	  else if (templateId.equals(IJ2EEModuleConstants.JST_APPCLIENT_TEMPLATE)) {
		  dm = DataModelFactory.createDataModel(new AppClientFacetProjectCreationDataModelProvider());
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, projectName);
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_RUNTIME, facetRuntime);		  
	  }
	  else if (templateId.equals(IJ2EEModuleConstants.JST_UTILITY_TEMPLATE)) {
		  dm = DataModelFactory.createDataModel(new UtilityProjectCreationDataModelProvider());
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, projectName);
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_RUNTIME, facetRuntime);
	  }
	  else if (templateId.equals(IJ2EEModuleConstants.JST_WEB_TEMPLATE) || containsWebFacet(requiredFixedFacets)) {
		  //we want any project with the web template ID, or that contains a jst.web facet to be created with this data model
		  dm = DataModelFactory.createDataModel(new WebFacetProjectCreationDataModelProvider());
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, projectName);
		  dm.setBooleanProperty(IJ2EEFacetProjectCreationDataModelProperties.ADD_TO_EAR, false);
		  dm.setProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_RUNTIME, facetRuntime);	  		  
	  }
	  return dm;
  }
  
  public IStatus execute(IProgressMonitor monitor, IAdaptable info)
  {
	  IStatus status = Status.OK_STATUS;

	  // check if data ready
	  status = checkDataReady();
	  if (status.getSeverity()==Status.ERROR)
	  {
		  return status;
	  }

	  IProject project = ProjectUtilities.getProject(projectName);
	  if (!project.exists())
	  {
		  try{
			  IProject createdProject;
			  IFacetedProject fproject;
			  Set facetsToAdd = getFacetsToAdd();

			  IDataModel dm = getDataModelForTemplate(facetsToAdd);
			  if (dm != null) {
				  //we found a project creation data model for this template id.  use it to create the project

				  Set missingFacets = new HashSet();

				  //here we look at the facet versions in facetsToAdd and set the version on the data model to match
				  //if no facet data model is found we add it to the missingFacets collection to add later  
				  if (dm.isProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP)) {
					  for (Iterator iter = facetsToAdd.iterator(); iter.hasNext();) {
						  IProjectFacetVersion requiredFacetVersion = (IProjectFacetVersion) iter.next();
						  final FacetDataModelMap map = (FacetDataModelMap) dm.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP);
						  IDataModel facetDM = map.getFacetDataModel(requiredFacetVersion.getProjectFacet().getId());
						  if (facetDM != null) {
							  facetDM.setStringProperty(IFacetDataModelProperties.FACET_VERSION_STR,  requiredFacetVersion.getVersionString());
						  } else {
							  missingFacets.add(requiredFacetVersion);
						  }
					  }
				  }

				  dm.getDefaultOperation().execute(null, null);
				  createdProject = ProjectUtilities.getProject(projectName);
				  fproject = ProjectFacetsManager.create(createdProject);

				  //add any facets that were not added by the project creation data model
				  if (missingFacets.size() > 0) {
					  status = FacetUtils.addFacetsToProject(fproject, missingFacets);
					  if (status.getSeverity() == IStatus.ERROR) {
						  return status;
					  }
				  }
			  }
			  else {
				  //did not find a project creation data model.  create the project and install facets manually
				  status = FacetUtils.createNewFacetedProject(projectName);
				  if (status.getSeverity() == IStatus.ERROR) {
					  return status;
				  }

				  createdProject = ProjectUtilities.getProject(projectName);
				  fproject = ProjectFacetsManager.create(createdProject);

				  //Install the facet versions
				  status = FacetUtils.addFacetsToProject(fproject, facetsToAdd);
				  if (status.getSeverity() == IStatus.ERROR) {
					  return status;
				  }
				  //Set the installed facet versions as fixed.
				  Set newFacetVersions = fproject.getProjectFacets();
				  Set fixedFacets = new HashSet();
				  for (Iterator iter = newFacetVersions.iterator(); iter.hasNext();) {
					  IProjectFacetVersion facetVersion = (IProjectFacetVersion) iter.next();
					  fixedFacets.add(facetVersion.getProjectFacet());
				  }
				  status = FacetUtils.setFixedFacetsOnProject(fproject, fixedFacets);
				  if (status.getSeverity() == IStatus.ERROR) {
					  return status;
				  }
			  }

			  //Set the runtime        
			  if (facetRuntime != null) {
				  status = FacetUtils.setFacetRuntimeOnProject(fproject, facetRuntime);
			  }

			  // add facets required by Web service runtime
			  if (requiredFacetVersions.length != 0) {
				  status = FacetUtils.addRequiredFacetsToProject(project, requiredFacetVersions, monitor);
				  if (status.getSeverity() == Status.ERROR) {
					  return status;
				  }
			  }

			  if (facetRuntime != null) {
				  // add the default facets that's not in conflict with the existing facets
				  Set projectFacetVersionSet = fproject.getProjectFacets();
				  Set projectFacetSet = new HashSet();
				  // get the project facet from the project facet version we calculated
				  for (Iterator iter = projectFacetVersionSet.iterator(); iter.hasNext();) {
					  IProjectFacetVersion pfv = (IProjectFacetVersion) iter.next();
					  projectFacetSet.add(pfv.getProjectFacet());
				  }
				  try {
					  Set defaultProjectFacetVersionSet = facetRuntime.getDefaultFacets(projectFacetSet);
					  // The returned defaultFacetSet contains the original projectFacetSet passed into getDefaultFacets
					  // plus any default facets that are not in conflict with the original projectFacetSet.
					  // Add to facetsToAdd if the the default facet is not in the original set.
					  Set defaultFacetsToAdd = new HashSet();
					  for (Iterator iter = defaultProjectFacetVersionSet.iterator(); iter.hasNext();) {
						  IProjectFacetVersion defaultProjFacetVersion = (IProjectFacetVersion) iter.next();
						  if( ! projectFacetSet.contains( defaultProjFacetVersion.getProjectFacet() ) )
						  {
							  defaultFacetsToAdd.add(defaultProjFacetVersion);
						  }
					  }
					  if (!defaultFacetsToAdd.isEmpty()) {
						  status = FacetUtils.addFacetsToProject(fproject, defaultFacetsToAdd);
						  if (status.getSeverity() == IStatus.ERROR) {
							  return status;
						  }
					  }
				  } catch (CoreException e) {
					  // If there's any exception when trying to get the default facet, just ignore the default facet
					  // and return the original facetsToAdd.
				  }
			  }
		  }
		  catch (CoreException ce) {
			  return StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }));
		  }
		  catch (ExecutionException e) {
			  return StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }));
		  }

	  }

	  return status;
  }
    
  private IStatus checkDataReady()
  {

	if (projectName == null)
    {
      return StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] {projectName}));
    }

    return Status.OK_STATUS;
  }
  
  /**
   * Returns the set of facets to install on the new project. The set will consist
   * of the highest version of each of the template's fixed facets that satisfies
   * the required facet versions, the facet runtime, and the EAR project J2EE level.
   * @return Set a Set containing elements of type IProjectFacetVersion.
   */
  private Set getFacetsToAdd()
  {
    Set facets = null;
    
    //Set the facet runtime.
    setFacetRuntime();
    //Get all facet version combinations for the template in order of ascending version numbers.
    Set[] allCombinations = FacetSetsByTemplateCache.getInstance().getFacetVersionCombinationsFromTemplate(templateId);
    int n = allCombinations.length;
    if (facetRuntime != null)
    {
      //Walk the facet version combinations in order of descending version numbers.
      for (int i=n-1; i>=0; i--)
      {
        //Check this template combination to see if it is compatible with the 
        //required facet versions, the server runtime, and the EAR. If it is, choose it.
        Set combination = allCombinations[i];
        FacetMatcher fm = FacetUtils.match(requiredFacetVersions, combination);
        if (fm.isMatch())
        {
          //Check against Runtime & EAR
          if (FacetUtils.doesRuntimeSupportFacets(facetRuntime, combination)  && doesEARSupportFacets(combination) )
          {
            //We have a match. Use this combination of facet versions for project creation.
            facets = combination;
            break;
          }
        }                
      }
      
    }
    else
    {
      for (int i=n-1; i>=0; i--)
      {
        //Check this template combination to see if it is compatible with both the 
        //service/client runtime and the server runtime. If it is, choose it.
        Set combination = allCombinations[i];
        FacetMatcher fm = FacetUtils.match(requiredFacetVersions, combination);
        if (fm.isMatch())
        {
            //We have a match. Use this combination of facet versions for project creation.
            facets = combination;
            break;
        }                
      }      
    }
   
    //Unlikely to get to this point in the code, but if we do, choose the highest version
    //of each fixed facet in the template that is supported by the server runtime
    if (facets == null)
    {
      facets = getHighestFacetVersionsFromTemplateAndServer();
    }
     
    return facets;
  }

  /**
   * Sets the facetRuntime attribute based on the serverInstanceId or serverFactoryId
   * Preference is given to non-stub facet runtimes.
   */
  private void setFacetRuntime()
  {
    
	  if (serverInstanceId != null && serverInstanceId.length()>0)
	  {
		  IServer server = ServerCore.findServer(serverInstanceId);
		  IRuntime sRuntime = server.getRuntime();
		  facetRuntime = FacetUtil.getRuntime(sRuntime);      
	  }
	  else
	  {
		  if (serverFactoryId != null && serverFactoryId.length() > 0)
		  {
			  //Find a non Stub runtime that matches this server type
			  IRuntime serverRuntime = ServerUtils.getNonStubRuntime(serverFactoryId);
			  if (serverRuntime != null)
			  {
				  facetRuntime = FacetUtil.getRuntime(serverRuntime);
			  }
			  else
			  {
				  //Accept stub runtime.
				  IServerType st = ServerCore.findServerType(serverFactoryId);
				  String runtimeTypeId = st.getRuntimeType().getId();   
				  //Find the facet runtime
				  IRuntime[] runtimes = ServerCore.getRuntimes();
				  for (int i=0; i<runtimes.length; i++)
				  {
					  IRuntime sRuntime = runtimes[i];
					  if (sRuntime.getRuntimeType().getId().equals(runtimeTypeId))
					  {
						  facetRuntime = FacetUtil.getRuntime(sRuntime);
					  }
				  }                
			  }
		  }
	  }
  }  
  
  public void setProjectName(String projectName)
  {
    this.projectName = projectName;
  }  
  
  public void setTemplateId(String templateId)
  {
    this.templateId = templateId;
  }    

  public void setRequiredFacetVersions(RequiredFacetVersion[] requiredFacetVersions)
  {
    this.requiredFacetVersions = requiredFacetVersions;
  }

  public void setServerFactoryId(String serverFactoryId)
  {
    this.serverFactoryId = serverFactoryId;
  }

  public void setServerInstanceId(String serverInstanceId)
  {
    this.serverInstanceId = serverInstanceId;
  }
  public void setEarProjectName(String earProject) {
	  this.earProjectName = earProject;
  }
  
	private RequiredFacetVersion[] getRequiredWebFacets() {
		return new RequiredFacetVersion[] { getRequiredFacetVersion(
				IModuleConstants.JST_WEB_MODULE,
				J2EEUtils.getWebJ2EEVersionFromEARJ2EEVersion(ProjectUtilities.getProject(earProjectName))) };
	}

	private RequiredFacetVersion[] getRequiredAppClientFacets() {
		return new RequiredFacetVersion[] { getRequiredFacetVersion(
				IModuleConstants.JST_APPCLIENT_MODULE,
				J2EEUtils.getAppClientJ2EEVersionFromEARJ2EEVersion(ProjectUtilities.getProject(earProjectName))) };
	}

	private RequiredFacetVersion[] getRequiredEJBFacets() {
		return new RequiredFacetVersion[] { getRequiredFacetVersion(
				IModuleConstants.JST_EJB_MODULE,
				J2EEUtils.getEJBJ2EEVersionFromEARJ2EEVersion(ProjectUtilities.getProject(earProjectName))) };
	}

	private boolean doesEARSupportFacets(Set combination) {
		try {

			if (earProjectName == null || earProjectName.length() == 0
					|| !ProjectUtilities.getProject(earProjectName).exists())
				// the ear does not exist or the project type template is
				// undefined
				return true;
			else {
				if (combinationContainsFacet(combination, IModuleConstants.JST_WEB_MODULE))
					return FacetUtils
							.match(getRequiredWebFacets(), combination)
							.isMatch();
				else if (combinationContainsFacet(combination, IModuleConstants.JST_EJB_MODULE))
					return FacetUtils
							.match(getRequiredEJBFacets(), combination)
							.isMatch();
				else if (combinationContainsFacet(combination, IModuleConstants.JST_APPCLIENT_MODULE))
					return FacetUtils.match(getRequiredAppClientFacets(),
							combination).isMatch();
				else
					return true;
			}
		} catch (Exception e) {
			return true;
		}
	}

	private boolean combinationContainsFacet(Set combination, String facetName) {
		if (combination == null || facetName == null || facetName.length() == 0)
			return false;
        for (Iterator iter = combination.iterator(); iter.hasNext();) {
        	IProjectFacetVersion nextFacetVersion = (IProjectFacetVersion) iter.next();
        	if (facetName.equals(nextFacetVersion.getProjectFacet().getId()))
        			return true;
		}
        return false;
	}

	private RequiredFacetVersion getRequiredFacetVersion(String facetName,
			String facetVersion) {
		IProjectFacet projectFacet = ProjectFacetsManager
				.getProjectFacet(facetName);
		IProjectFacetVersion projFacetVersion = projectFacet
				.getVersion(facetVersion);
		RequiredFacetVersion reqFacetVersion = new RequiredFacetVersion();
		reqFacetVersion.setAllowNewer(false);
		reqFacetVersion.setProjectFacetVersion(projFacetVersion);
		return reqFacetVersion;
	}

	  private Set getHighestFacetVersionsFromTemplateAndServer()
	  {
	    IFacetedProjectTemplate template = ProjectFacetsManager.getTemplate(templateId);
	    Set fixedFacets = template.getFixedProjectFacets(); 
	    HashSet initial = new HashSet(); 
	    for (Iterator itr = fixedFacets.iterator(); itr.hasNext(); ) 
	    { 
	      IProjectFacet facet = (IProjectFacet) itr.next(); 
	      IProjectFacetVersion highestFacetVersion = null;
	      try {
	    	  highestFacetVersion = facet.getLatestSupportedVersion(facetRuntime);
	      } catch (CoreException e) {
	    	  try {
	    		  highestFacetVersion = facet.getLatestVersion();
	    	  } catch (CoreException e2) {
	    		  //not much we can do here
	    	  }
	    	  
	      }
	      initial.add(highestFacetVersion); 
	    }             
	    
	    return initial;
	  }
}
