/*******************************************************************************
 * 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 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
 *******************************************************************************/

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.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.server.core.FacetUtil;
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.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
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; 

  //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;
  
  
  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
      {
        status = FacetUtils.createNewFacetedProject(projectName);
        if (status.getSeverity() == IStatus.ERROR)
        {
          return status;
        }
        
        IProject createdProject = ProjectUtilities.getProject(projectName);
        IFacetedProject fproject = ProjectFacetsManager.create(createdProject);
        
        //Get the facet versions to install. 
        Set facetsToAdd = getFacetsToAdd();
        
        //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.
        	}
        	// end of adding default facets
        }
      } catch (CoreException ce)
      {
        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 satifies
   * both the required facet versions and the facet runtime.
   * @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;

	  Set defaultFacets = FacetUtils.getDefaultFacetVersionsFromTemplate(templateId);
	  int defaultIndex = n-1; // set default to highest versions
	  if (!defaultFacets.isEmpty()) {
		// find the index of the defaultFacet within all combinations
		  for (int i=n-1; i>=0; i--)
		  {
			  Set combo = allCombinations[i];
			  if (combo.equals (defaultFacets)) {
				  defaultIndex = i;
				  break;
			  }
		  }
	  } else {
		  // get the highest versions of all facets
		  defaultFacets = FacetUtils.getInitialFacetVersionsFromTemplate(templateId);
	  }
	  
	  // walk the facet version combinations from default version up to higher versions
	  for (int i=defaultIndex; i<n; i++) 
	  {
		  //Check the template combination to see if it is compatible with both the 
		  //required facet versions and the server runtime. If it is, choose it.
		  Set combination = allCombinations[i];
		  FacetMatcher fm = FacetUtils.match(requiredFacetVersions, combination);
		  if (fm.isMatch())
		  {
			  if (facetRuntime != null)
			  {
				  if (FacetUtils.doesRuntimeSupportFacets(facetRuntime, combination))
				  {
					  facets = combination;
					  break;
				  }
			  } else {
				  facets = combination;
				  break;
			  }
		  }                
	  }
	  if (facets == null)
	  {
		  // walk the facet version combinations from default version down to lower versions
		  for (int i=defaultIndex-1; i>=0; i--) 
		  {
			  Set combination = allCombinations[i];
			  FacetMatcher fm = FacetUtils.match(requiredFacetVersions, combination);
			  if (fm.isMatch())
			  {
				  if (facetRuntime != null)
				  {
					  if (FacetUtils.doesRuntimeSupportFacets(facetRuntime, combination))
					  {
						  facets = combination;
						  break;
					  }
				  } else {
					  facets = combination;
					  break;
				  }
			  }                
		  }
	  }

	  //Unlikely to get to this point in the code, but if we do, choose the default version
	  //of each fixed facet in the template.
	  if (facets == null)
	  {
		  facets = defaultFacets;
	  }
     
    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;
  }

  
  

}
