/*******************************************************************************
 * Copyright (c) 2003, 2004 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.jst.ws.internal.consumption.command.common;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.web.archive.operations.WebComponentCreationDataModelProvider;
import org.eclipse.jst.j2ee.web.datamodel.properties.IWebComponentCreationDataModelProperties;
import org.eclipse.jst.ws.internal.common.EnvironmentUtils;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.common.ServerUtils;
import org.eclipse.jst.ws.internal.consumption.common.WebServiceStartServerRegistry;
import org.eclipse.jst.ws.internal.consumption.plugin.WebServiceConsumptionPlugin;
import org.eclipse.wst.command.internal.provisional.env.core.SimpleCommand;
import org.eclipse.wst.command.internal.provisional.env.core.common.Environment;
import org.eclipse.wst.command.internal.provisional.env.core.common.Log;
import org.eclipse.wst.command.internal.provisional.env.core.common.MessageUtils;
import org.eclipse.wst.command.internal.provisional.env.core.common.SimpleStatus;
import org.eclipse.wst.command.internal.provisional.env.core.common.Status;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerUtil;

public class CreateWebProjectCommand extends SimpleCommand {

  private final static String DESCRIPTION = "TASK_DESC_CREATE_WEB_PROJECT";
  private final static String LABEL = "TASK_LABEL_CREATE_WEB_PROJECT";
  private final String DEFAULT_EAR_NAME = "WebServiceEAR";
  private String projectName_ = null;
  private String earProjectName_ = null;
  private boolean proxyCodegenEnabled = true;
  private String serverFactoryId_;
  private String j2eeVersion_;
  private IServer existingServer_;
  private boolean needEAR_;
  private boolean weAddedProjectToServer_ = false;
  private MessageUtils msgUtils_;

  /**
   * Default CTOR
   */
  public CreateWebProjectCommand() {

    super(LABEL, DESCRIPTION);
    String       pluginId = "org.eclipse.jst.ws.consumption";
    msgUtils_ = new MessageUtils( pluginId + ".plugin", this );
    //setRunInWorkspaceModifyOperation(false);
  }

  /**
   * Create service Web Project using the parameter Project name Note: to be
   * deprecated
   */
  public CreateWebProjectCommand(String serviceProjectName) {

    super(LABEL, DESCRIPTION);
    projectName_ = serviceProjectName;
    //setRunInWorkspaceModifyOperation(false);
  }

  public Status execute(Environment env) {

    if (projectName_ == null || projectName_.length() == 0) {
    	env.getLog().log(Log.ERROR, 5044, this, "execute", "Web project name not set");
      Status status = new SimpleStatus(WebServiceConsumptionPlugin.ID, msgUtils_.getMessage("MSG_ERROR_WEB_PROJECT_CREATE"), Status.ERROR, null);
      env.getStatusHandler().reportError(status);
      return status; 
    }

    if (existingServer_ == null)
    {
      env.getLog().log(Log.ERROR, 5044, this, "execute", "Server is null");
      Status status = new SimpleStatus(WebServiceConsumptionPlugin.ID, msgUtils_.getMessage("MSG_ERROR_WEB_PROJECT_CREATE"), Status.ERROR, null);
      env.getStatusHandler().reportError(status);
      return status;      
    }
    
    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    IProject webProject = root.getProject(projectName_);
    IProject earProject = null;
    if (earProjectName_!=null && earProjectName_.length()>0)
    {
      earProject = root.getProject(earProjectName_);
    }
    
    boolean projectExists = webProject != null && webProject.exists();
    boolean addedToServer = false;
    if (projectExists)
    {
      addedToServer = ServerUtil.containsModule(existingServer_,ResourceUtils.getModule(webProject), new NullProgressMonitor());
    }
    
    boolean earExists = earProject!=null && earProject.exists();
    boolean earAddedToServer = true;
    if (earExists)
    {
      earAddedToServer = ServerUtil.containsModule(existingServer_,ResourceUtils.getModule(earProject), new NullProgressMonitor());
    }
    
    boolean areAssociated = false;
//  TODO Remove old Nature refs
//    if (projectExists && earExists)
//    {
//      areAssociated = J2EEUtils.isEARAssociated(webProject, earProject);
//    }
    
    boolean serverRequiresEARRemoval = true;
    try
    {
      // check the Registry to see if the server requires EAR removal
      if (serverFactoryId_!=null)
      {
        WebServiceStartServerRegistry wssReg = WebServiceStartServerRegistry.getInstance();
        serverRequiresEARRemoval = wssReg.isRemoveEARRequired(serverFactoryId_);    		
      }    
    } catch (CoreException ce)
    {
      env.getLog().log(Log.ERROR, 5046, this, "execute", ce);
      Status status = new SimpleStatus(WebServiceConsumptionPlugin.ID, msgUtils_.getMessage("MSG_ERROR_WEB_PROJECT_CREATE"), Status.ERROR, ce);
      env.getStatusHandler().reportError(status);
      return status;
    }
    
    
    if (!needEAR_ && projectExists && addedToServer && !weAddedProjectToServer_)
    {
      return new SimpleStatus("");
    }
    
    // existing project, ear and server configuration
    if (needEAR_ && projectExists && earExists && earAddedToServer && areAssociated && !weAddedProjectToServer_){
    	return new SimpleStatus("");
    }
    
    //Always stop the server
    Status stoppingStatus = stopServer(env);
    if(stoppingStatus.getSeverity() == Status.ERROR)
        return stoppingStatus;
    
    if (!needEAR_ && projectExists && addedToServer)
    {
      return new SimpleStatus("");
    }       
    else if (!needEAR_ && projectExists && !addedToServer)
    {
      Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());
      if (mmStatus.getSeverity()==Status.ERROR)
    	return mmStatus;      
    }
    else if (!needEAR_ && !projectExists)
    {
      Status status = createWebProject(env);
      if(status.getSeverity() == Status.ERROR)
        return status;
      webProject = root.getProject(projectName_);
      
      Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());
      if (mmStatus.getSeverity()==Status.ERROR)
    	return mmStatus;    
    }
    else if (projectExists && earExists && areAssociated && addedToServer)
    {
      return new SimpleStatus("");
    }
    else if (projectExists && earExists && areAssociated && !addedToServer)
    {
      Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());
      if (mmStatus.getSeverity()==Status.ERROR)
    	return mmStatus;    
    }
    else if (projectExists && !earExists)
    {
      //Create the EAR project
      Status status = createEARProject(env);
      if (status.getSeverity() == Status.ERROR)
        return status;
      earProject = root.getProject(earProjectName_);
      
      //Associate the Web project and the EAR project
//    TODO Remove old Nature refs
      //J2EEUtils.associateWebProject(webProject, earProject);
      
      //Add to server
      Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());
      if (mmStatus.getSeverity()==Status.ERROR)
    	return mmStatus;    
    }
    else if (!projectExists && !earExists)
    {
      //Create EAR
      Status status = createEARProject(env);
      if (status.getSeverity() == Status.ERROR)
        return status;
      earProject = root.getProject(earProjectName_);
      
      //Create project
      status = createWebProject(env);
      if(status.getSeverity() == Status.ERROR)
        return status;
      webProject = root.getProject(projectName_);
      
      //Add to server
      Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());
      if (mmStatus.getSeverity()==Status.ERROR)
    	return mmStatus;      
    }
    else if (!projectExists && earExists)
    {
      //Remove the ear from the server if necessary
      if (earAddedToServer && serverRequiresEARRemoval)
      {
        // Stopping server and removing EAR from Server
        if (existingServer_.getServerState() != IServer.STATE_STOPPED)
        {
          existingServer_.synchronousStop(false);
        }        
        Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(earProject), false, new NullProgressMonitor());
        if (mmStatus.getSeverity()==Status.ERROR)
        	return mmStatus;      
      }
      
      //Create the Web project
      Status status = createWebProject(env);
      if(status.getSeverity() == Status.ERROR)
        return status;
      webProject = root.getProject(projectName_);

      boolean earAddedToServerFinal = ServerUtil.containsModule(existingServer_,ResourceUtils.getModule(earProject), new NullProgressMonitor());
      if (!earAddedToServerFinal)
      {
      	Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());  
        if (mmStatus.getSeverity()==Status.ERROR)
        	return mmStatus;      
      }
      
    }
    else if (projectExists && earExists && !areAssociated)
    {
      //Remove the ear from the server if necessary
      if (earAddedToServer && serverRequiresEARRemoval)
      {
        // Stopping server and removing EAR from Server
        if (existingServer_.getServerState() != IServer.STATE_STOPPED)
        {
          existingServer_.synchronousStop(false);
        }        
        Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(earProject), false, new NullProgressMonitor());
        if (mmStatus.getSeverity()==Status.ERROR)
        	return mmStatus;      
      }
      
      //Associate the Web project and the EAR project
//    TODO Remove old Nature refs
      //J2EEUtils.associateWebProject(webProject, earProject);
      
      boolean earAddedToServerFinal = ServerUtil.containsModule(existingServer_,ResourceUtils.getModule(earProject), new NullProgressMonitor());      
      if (!earAddedToServerFinal)
      {
      	Status mmStatus = ServerUtils.getInstance().modifyModules(env, existingServer_, ResourceUtils.getModule(webProject) , true, new NullProgressMonitor());  
        if (mmStatus.getSeverity()==Status.ERROR)
        	return mmStatus;      
      }      
      
    }

    return new SimpleStatus("");
  }

  private Status createWebProject(Environment env)
  {
    try
    {
    	
    IDataModel projectInfo = DataModelFactory.createDataModel(new WebComponentCreationDataModelProvider());
    projectInfo.setProperty(IWebComponentCreationDataModelProperties.PROJECT_NAME, projectName_);
    String finalJ2EEVersion = null;
    if (j2eeVersion_ != null && j2eeVersion_.length()>0)
    {
      projectInfo.setProperty(IWebComponentCreationDataModelProperties.COMPONENT_VERSION, new Integer(j2eeVersion_));
      finalJ2EEVersion = j2eeVersion_;
    }        
    else        
    {
      if (earProjectName_ !=null && earProjectName_.length()>0)
      {
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IProject earProject = root.getProject(earProjectName_);
        if (earProject != null && earProject.exists())
        {
        //TODO Remove old Nature refs
          //EARNatureRuntime ear = EARNatureRuntime.getRuntime(earProject);
          int earVersion = J2EEUtils.getJ2EEVersion(earProject);
          projectInfo.setProperty(IWebComponentCreationDataModelProperties.COMPONENT_VERSION, new Integer(earVersion));
          finalJ2EEVersion = String.valueOf(earVersion);
        }
        else
        {          
          projectInfo.setProperty(IWebComponentCreationDataModelProperties.COMPONENT_VERSION, new Integer(J2EEVersionConstants.J2EE_1_3_ID));
          finalJ2EEVersion = String.valueOf(J2EEVersionConstants.J2EE_1_3_ID);
        }
      }
      else
      {
        projectInfo.setProperty(IWebComponentCreationDataModelProperties.COMPONENT_VERSION, new Integer(J2EEVersionConstants.J2EE_1_3_ID));
        finalJ2EEVersion = String.valueOf(J2EEVersionConstants.J2EE_1_3_ID);        
      }
      
    }    
    String runtimeTargetId = null;
    if (serverFactoryId_!=null && serverFactoryId_.length()>0)
    {
//		TODO - Add this logic to FlexibleProjectCreationDataModel, and op....
//      runtimeTargetId = ServerUtils.getServerTargetIdFromFactoryId(serverFactoryId_,IServerTargetConstants.WEB_TYPE, finalJ2EEVersion); 
//      projectInfo.setProperty(WebComponentCreationDataModel.SERVER_TARGET_ID, runtimeTargetId );
//      projectInfo.setProperty(WebComponentCreationDataModel.ADD_SERVER_TARGET, Boolean.TRUE);      
    } 
    
    if (earProjectName_ !=null && earProjectName_.length()>0)
    {
      projectInfo.setProperty(IWebComponentCreationDataModelProperties.EAR_COMPONENT_NAME, earProjectName_);
      projectInfo.setProperty(IWebComponentCreationDataModelProperties.ADD_TO_EAR, Boolean.TRUE);
    }
    else
    {
      projectInfo.setProperty(IWebComponentCreationDataModelProperties.ADD_TO_EAR, Boolean.FALSE);
    }
    	
    

    //Create and run the operation
    IDataModelOperation op = projectInfo.getDefaultOperation();
      op.execute(new NullProgressMonitor(), null);    
    return new SimpleStatus("");
    } catch (Exception e)
    {
      env.getLog().log(Log.ERROR, 5046, this, "createWebProject", e);
      Status status = new SimpleStatus(WebServiceConsumptionPlugin.ID, msgUtils_.getMessage("MSG_ERROR_WEB_PROJECT_CREATE"), Status.ERROR, e);
      env.getStatusHandler().reportError(status);
      return status;      
    }
  }
  
  private Status createEARProject(Environment env)
  {
    CreateEARProjectCommand t = new CreateEARProjectCommand();
    t.setEarProjectName(earProjectName_);
    t.setServerFactoryId(serverFactoryId_);
    t.setJ2EEVersion(j2eeVersion_);
    Status status = t.execute(env);
    return status;
  }             
  
  private Status stopServer(Environment env)
  {
 	
    try
   	{
   		WebServiceStartServerRegistry reg = WebServiceStartServerRegistry.getInstance();
   		AbstractStartServer startServerCommand = (AbstractStartServer)reg.getServerStartByTypeId(existingServer_.getServerType().getId());
    	startServerCommand.stopServer(existingServer_);
    	return new SimpleStatus("");
   	}
  catch (CoreException ce )
  	{
    	IStatus embeddedStatus = ce.getStatus();
    	Status status = EnvironmentUtils.convertIStatusToStatus(embeddedStatus);
    	env.getStatusHandler().reportError(status);
  		return status;
  	}  	
  	

  }
  
  // To be deprecated
  /*
  private Status createWebProject(String webProjectName, String earProjectName, Environment env) {

    try {
      IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
      IProject earProject = root.getProject(earProjectName);
      if (earProject != null && !earProject.exists()) {
        CreateEARProjectCommand c = new CreateEARProjectCommand();
        c.setEarProjectName(earProjectName);
        c.setServerFactoryId(serverFactoryId_);
        c.setJ2EEVersion(j2eeVersion_);
        c.execute(env);
        earProject = root.getProject(earProjectName);
      }
      IProject webProject = root.getProject(webProjectName);
      if (webProject != null && !webProject.exists()) {
        WebComponentCreationDataModel info = new WebComponentCreationDataModel();
        info.setProperty(WebComponentCreationDataModel.PROJECT_NAME, webProjectName);
        info.setProperty(WebComponentCreationDataModel.EAR_PROJECT_NAME, earProjectName);
        //info.setProperty(WebComponentCreationDataModel.ADD_TO_EAR, Boolean.TRUE);
        info.setProperty(WebComponentCreationDataModel.ADD_TO_EAR, Boolean.FALSE);
        if (serverFactoryId_!=null && serverFactoryId_.length()>0)
        {
          String runtimeTargetId = ServerUtils.getRuntimeTargetIdFromFactoryId(serverFactoryId_); 
          info.setProperty(WebComponentCreationDataModel.SERVER_TARGET_ID, runtimeTargetId );
          info.setProperty(WebComponentCreationDataModel.ADD_SERVER_TARGET, Boolean.TRUE);
        }
        if (j2eeVersion_ != null && j2eeVersion_.length()>0)
        {
          info.setProperty(WebComponentCreationDataModel.J2EE_VERSION, new Integer(j2eeVersion_));
        }                

        WebProjectCreationOperation operation = new WebProjectCreationOperation(info);
        operation.run(new NullProgressMonitor());
      }
    }
    catch (java.lang.reflect.InvocationTargetException ite) {
      return new SimpleStatus(WebServiceConsumptionPlugin.ID, msgUtils_.getMessage("MSG_ERROR_WEB_PROJECT_CREATE"), Status.ERROR,
          ite);
    }
    catch (InterruptedException ie) {
      return new SimpleStatus(WebServiceConsumptionPlugin.ID, msgUtils_.getMessage("MSG_ERROR_WEB_PROJECT_CREATE"), Status.ERROR,
          ie);
    }
    return new SimpleStatus("");
  }
  */
  
  private String getNewEARName() {

    String newEARName = DEFAULT_EAR_NAME;
    //Check to see if it exists
    IProject project = ResourceUtils.getWorkspace().getRoot().getProject(newEARName);
    return newEARName;
  }

  //TODO Remove old Nature refs
//  private IProject getDefaultEARProject(IProject project) {
//
//    try {
//      EARNatureRuntime[] ears = null;
//      EARNatureRuntime ear = null;
//      ears = J2EEProjectUtilities.getReferencingEARProjects(project);
//      if (ears[0] != null && ears.length >= 1) {
//        // found an EAR containing the web project
//        return ears[0].getProject();
//      }
//
//      if (j2eeVersion_!=null && j2eeVersion_.length()>0)
//      {
//      	ear = J2EEUtils.getEAR(Integer.parseInt(j2eeVersion_));
//      }
//      else
//      {
//        ear = J2EEUtils.get12EAR();
//        if (ear == null)
//          ear = J2EEUtils.get13EAR();
//        if (ear == null)
//          ear = J2EEUtils.getEAR(J2EEVersionConstants.J2EE_1_4_ID);
//      }
//      
//      if (ear != null)
//        return ear.getProject();
//      else {
//        String earName = getNewEARName();
//        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
//        return root.getProject(earName);
//      }
//    }
//    catch (Exception e) {
//      return null;
//    }
//
//  }

  /**
   * @param earProjectName
   *          The earProjectName to set.
   */
  public void setEarProjectName(String earProjectName) {

    this.earProjectName_ = earProjectName;
  }

  /**
   * @param projectName
   *          The projectName to set.
   */
  public void setProjectName(String projectName) {

    this.projectName_ = projectName;
  }

  /**
   * @param existingServer
   *          The existingServer to set.
   */
  public void setExistingServer(IServer existingServer) {

    this.existingServer_ = existingServer;
  }
  
  public void setServerFactoryId(String serverFactoryId)
  {
  	serverFactoryId_ = serverFactoryId;
  }
  
  public void setJ2EEVersion(String j2eeVersion)
  {
  	j2eeVersion_ = j2eeVersion;	
  }
  
  public void setNeedEAR(boolean needEAR)
  {
    needEAR_ = needEAR;
  }
  
  public void setAddedProjectToServer(boolean addedProjectToServer) 
  {
    weAddedProjectToServer_ = addedProjectToServer;
  }  
}
