/*******************************************************************************
 * Copyright (c) 2003, 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.jst.j2ee.internal.earcreation;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jst.j2ee.application.internal.operations.DefaultJ2EEComponentCreationOperation;
import org.eclipse.jst.j2ee.applicationclient.internal.creation.AppClientFacetProjectCreationDataModelProvider;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.moduleextension.EarModuleManager;
import org.eclipse.jst.j2ee.internal.moduleextension.EjbModuleExtension;
import org.eclipse.jst.j2ee.internal.moduleextension.JcaModuleExtension;
import org.eclipse.jst.j2ee.internal.moduleextension.WebModuleExtension;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetProjectCreationDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.IJ2EEModuleFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.J2EEModuleFacetInstallDataModelProvider;
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.frameworks.datamodel.AbstractDataModelProvider;
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.common.frameworks.internal.WTPPlugin;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;

public class DefaultJ2EEComponentCreationDataModelProvider extends AbstractDataModelProvider implements IDefaultJ2EEComponentCreationDataModelProperties {
	private static String CREATE_BASE = "DefaultJ2EEComponentCreationDataModel.CREATE_"; //$NON-NLS-1$

	private static final int EJB = 0;
	private static final int WEB = 1;
	private static final int RAR = 2;
	private static final int CLIENT = 3;

	private static final String WEB_SUFFIX = "Web"; //$NON-NLS-1$
	private static final String EJB_SUFFIX = "EJB"; //$NON-NLS-1$
	private static final String CLIENT_SUFFIX = "Client"; //$NON-NLS-1$
	private static final String CONNECTOR_SUFFIX = "Connector"; //$NON-NLS-1$

	private IDataModel ejbModel;
	private IDataModel ejbFacetModel;
	private IDataModel webModel;
	private IDataModel webFacetModel;
	private IDataModel jcaModel;
	private IDataModel jcaFacetModel;
	private IDataModel clientModel;
	private IDataModel clientFacetModel;
	
	private List <IDataModel> extendedModelsToDispose = new ArrayList<IDataModel>();

	public DefaultJ2EEComponentCreationDataModelProvider() {
		super();
	}

	@Override
	public Set getPropertyNames() {
		Set propertyNames = super.getPropertyNames();
		propertyNames.add(PROJECT_NAME);
		propertyNames.add(EAR_COMPONENT_NAME);
		propertyNames.add(APPCLIENT_COMPONENT_NAME);
		propertyNames.add(WEB_COMPONENT_NAME);
		propertyNames.add(EJB_COMPONENT_NAME);
		propertyNames.add(CONNECTOR_COMPONENT_NAME);
		propertyNames.add(J2EE_VERSION);
		propertyNames.add(CREATE_EJB);
		propertyNames.add(CREATE_WEB);
		propertyNames.add(CREATE_APPCLIENT);
		propertyNames.add(CREATE_CONNECTOR);
		propertyNames.add(MODULE_NAME_COLLISIONS_VALIDATION);
		propertyNames.add(ENABLED);
		propertyNames.add(NESTED_MODEL_CLIENT);
		propertyNames.add(NESTED_MODEL_EJB);
		propertyNames.add(NESTED_MODEL_JCA);
		propertyNames.add(NESTED_MODEL_WEB);
		propertyNames.add(FACET_RUNTIME);
		return propertyNames;
	}


	@Override
	public IDataModelOperation getDefaultOperation() {
		return new DefaultJ2EEComponentCreationOperation(model);
	}

	@Override
	public void init() {
		initNestedCreationModels();
		super.init();
	}

	protected void initNestedCreationModels() {
		clientModel = DataModelFactory.createDataModel(new AppClientFacetProjectCreationDataModelProvider());
		extendedModelsToDispose.add(clientModel);
		model.addNestedModel(NESTED_MODEL_CLIENT, clientModel);
		clientFacetModel = ((FacetDataModelMap)clientModel.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP)).getFacetDataModel(J2EEProjectUtilities.APPLICATION_CLIENT);
		clientFacetModel.setBooleanProperty(IJ2EEModuleFacetInstallDataModelProperties.ADD_TO_EAR, false);
		clientFacetModel.setBooleanProperty(J2EEModuleFacetInstallDataModelProvider.PROHIBIT_ADD_TO_EAR, true);
		
		EjbModuleExtension ejbExt = EarModuleManager.getEJBModuleExtension();
		if (ejbExt != null) {
			ejbModel = ejbExt.createProjectDataModel();
			if (ejbModel != null){
				extendedModelsToDispose.add(ejbModel);
				model.addNestedModel(NESTED_MODEL_EJB, ejbModel);
				ejbFacetModel = ((FacetDataModelMap)ejbModel.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP)).getFacetDataModel(J2EEProjectUtilities.EJB);
				ejbFacetModel.setBooleanProperty(IJ2EEModuleFacetInstallDataModelProperties.ADD_TO_EAR, false);
				ejbFacetModel.setBooleanProperty(J2EEModuleFacetInstallDataModelProvider.PROHIBIT_ADD_TO_EAR, true);
			}
		}
		WebModuleExtension webExt = EarModuleManager.getWebModuleExtension();
		if (webExt != null) {
			webModel = webExt.createProjectDataModel();
			if (webModel != null){
				extendedModelsToDispose.add(webModel);
				model.addNestedModel(NESTED_MODEL_WEB, webModel);
				webFacetModel = ((FacetDataModelMap)webModel.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP)).getFacetDataModel(J2EEProjectUtilities.DYNAMIC_WEB);
				webFacetModel.setBooleanProperty(IJ2EEModuleFacetInstallDataModelProperties.ADD_TO_EAR, false);
				webFacetModel.setBooleanProperty(J2EEModuleFacetInstallDataModelProvider.PROHIBIT_ADD_TO_EAR, true);
			}
		}
		JcaModuleExtension rarExt = EarModuleManager.getJCAModuleExtension();
		if (rarExt != null) {
			jcaModel = rarExt.createProjectDataModel();
			if (jcaModel != null){
				extendedModelsToDispose.add(jcaModel);
				model.addNestedModel(NESTED_MODEL_JCA, jcaModel);
				jcaFacetModel = ((FacetDataModelMap)jcaModel.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP)).getFacetDataModel(J2EEProjectUtilities.JCA);
				jcaFacetModel.setBooleanProperty(IJ2EEModuleFacetInstallDataModelProperties.ADD_TO_EAR, false);
				jcaFacetModel.setBooleanProperty(J2EEModuleFacetInstallDataModelProvider.PROHIBIT_ADD_TO_EAR, true);
			}
		}
	}

	@Override
	public Object getDefaultProperty(String propertyName) {
		if (propertyName.startsWith(CREATE_BASE))
			return getDefaultCreateValue(propertyName);
		if (propertyName.equals(ENABLED))
			return Boolean.TRUE;
		return super.getDefaultProperty(propertyName);
	}


	private Object getDefaultCreateValue(String propertyName) {
		if (propertyName.equals(CREATE_CONNECTOR)) {
			int version = getIntProperty(J2EE_VERSION);
			if (version < J2EEVersionConstants.J2EE_1_3_ID)
				return Boolean.FALSE;
		}
		return Boolean.TRUE;
	}

	private int convertPropertyNameToInt(String propertyName) {
		if (propertyName.equals(CREATE_WEB)) {
			return WEB;
		} else if (propertyName.equals(CREATE_EJB)) {
			return EJB;
		} else if (propertyName.equals(CREATE_CONNECTOR)) {
			return RAR;
		} else if (propertyName.equals(CREATE_APPCLIENT)) {
			return CLIENT;
		}
		return -1;
	}

	private String ensureUniqueProjectName(String projectName) {
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		String newName = projectName;
		int index = 0;
		IProject proj = root.getProject(newName);
		while (proj.exists()) {
			index++;
			newName = projectName + index;
			proj = root.getProject(newName);
		}
		return newName;
	}

	@Override
	public boolean propertySet(String propertyName, Object propertyValue) {
		boolean notify = super.propertySet(propertyName, propertyValue);
		if (propertyName.equals(J2EE_VERSION)) {
			updatedJ2EEVersion((Integer) propertyValue);
			return true;
		}else if (propertyName.startsWith(CREATE_BASE)){
			notifyEnablement(convertPropertyNameToInt(propertyName));
		}else if (propertyName.equals(EAR_COMPONENT_NAME)) {
			setDefaultComponentNames((String) propertyValue);
		}else if(webModel != null && propertyName.equals(WEB_COMPONENT_NAME)){
			webModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, propertyValue);
		}else if(clientModel != null && propertyName.equals(APPCLIENT_COMPONENT_NAME)){
			clientModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, propertyValue);
		}else if(ejbModel != null && propertyName.equals(EJB_COMPONENT_NAME)){
			ejbModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, propertyValue);
		}else if(jcaModel != null && propertyName.equals(CONNECTOR_COMPONENT_NAME)){
			jcaModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, propertyValue);
		} 
		else if(FACET_RUNTIME.equals(propertyName)){
			if(webModel != null){
				webModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, propertyValue);
			}
			if(clientModel != null){
				clientModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, propertyValue);
			}
			if(ejbModel != null){
				ejbModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, propertyValue);
			}
			if(jcaModel != null){
				jcaModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, propertyValue);
			}
		}
		return notify;
	}

	private void notifyEnablement(int flag) {
		String propertyName = null;
		switch (flag) {
			case EJB :
				propertyName = EJB_COMPONENT_NAME;
				break;
			case WEB :
				propertyName = WEB_COMPONENT_NAME;
				break;
			case CLIENT :
				propertyName = APPCLIENT_COMPONENT_NAME;
				break;
			case RAR :
				propertyName = CONNECTOR_COMPONENT_NAME;
		}
		if (propertyName != null)
			model.notifyPropertyChange(propertyName, IDataModel.ENABLE_CHG);
	}

	private void updatedJ2EEVersion(Integer version) {
		setNestedJ2EEVersion(version);
		if (version.intValue() < J2EEVersionConstants.J2EE_1_3_ID && model.isPropertySet(CREATE_CONNECTOR)) {
			model.setProperty(CREATE_CONNECTOR, Boolean.FALSE);
		}
	}

	public IStatus validateModuleNameCollisions() {
		if (getBooleanProperty(ENABLED)) {
			ArrayList list = new ArrayList();
			String projectName = null;
			String actualProjectName = null;
			boolean errorCollision = false;
			boolean errorNoSelection = true;
			if (getBooleanProperty(CREATE_APPCLIENT)) {
				actualProjectName = clientModel.getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
				projectName = WTPPlugin.isPlatformCaseSensitive() ? actualProjectName : actualProjectName.toLowerCase();
				list.add(projectName);
				errorNoSelection = false;
			}
			if (getBooleanProperty(CREATE_EJB)) {
				actualProjectName = ejbModel.getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
				projectName = WTPPlugin.isPlatformCaseSensitive() ? actualProjectName : actualProjectName.toLowerCase();
				if (!list.contains(projectName)) {
					list.add(projectName);
				} else {
					errorCollision = true;
				}
				errorNoSelection = false;
			}
			if (!errorCollision && getBooleanProperty(CREATE_WEB)) {
				actualProjectName = webModel.getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
				projectName = WTPPlugin.isPlatformCaseSensitive() ? actualProjectName : actualProjectName.toLowerCase();
				if (!list.contains(projectName)) {
					list.add(projectName);
				} else {
					errorCollision = true;
				}
				errorNoSelection = false;
			}
			if (!errorCollision && getBooleanProperty(CREATE_CONNECTOR)) {
				actualProjectName = jcaModel.getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
				projectName = WTPPlugin.isPlatformCaseSensitive() ? actualProjectName : actualProjectName.toLowerCase();
				if (!list.contains(projectName)) {
					list.add(projectName);
				} else {
					errorCollision = true;
				}
				errorNoSelection = false;
			}
			if (errorCollision) {
				return J2EEPlugin.newErrorStatus(EARCreationResourceHandler.getString("DuplicateModuleNames", new Object[]{actualProjectName}), null); //$NON-NLS-1$
			} else if (errorNoSelection) {
				return J2EEPlugin.newErrorStatus(EARCreationResourceHandler.NoModulesSelected, null); 
			}
		}

		return OK_STATUS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModel#doValidateProperty(java.lang.String)
	 */
	@Override
	public IStatus validate(String propertyName) {

		if (getBooleanProperty(CREATE_APPCLIENT) && propertyName.equals(APPCLIENT_COMPONENT_NAME)) {
			return clientModel.validateProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
		}

		if (getBooleanProperty(CREATE_WEB) && propertyName.equals(WEB_COMPONENT_NAME)) {
			return webModel.validateProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
		}

		if (getBooleanProperty(CREATE_EJB) && propertyName.equals(EJB_COMPONENT_NAME)) {
			return ejbModel.validateProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
		}

		if (getBooleanProperty(CREATE_CONNECTOR) && propertyName.equals(CONNECTOR_COMPONENT_NAME)) {
			return jcaModel.validateProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
		}
		return super.validate(propertyName);
	}

//	private IStatus validateComponentName(String componentName) {
//		IStatus status = OK_STATUS;
//		if (status.isOK()) {
//			if (componentName.indexOf("#") != -1) { //$NON-NLS-1$
//				String errorMessage = WTPCommonPlugin.getResourceString(WTPCommonMessages.ERR_INVALID_CHARS); 
//				return WTPCommonPlugin.createErrorStatus(errorMessage);
//			} else if (componentName == null || componentName.equals("")) { //$NON-NLS-1$
//				String errorMessage = WTPCommonPlugin.getResourceString(WTPCommonMessages.ERR_EMPTY_MODULE_NAME);
//				return WTPCommonPlugin.createErrorStatus(errorMessage);
//			}
//		}
//		return status;
//	}

	private void setDefaultNestedComponentName(String name, int flag) {
		IDataModel modModule = getNestedModel(flag);
		if (modModule != null) {
			String compName = ensureUniqueProjectName(name);
			modModule.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, compName);
		}
	}

	private void setDefaultComponentNames(String base) {
		String componentName;
		if (base.endsWith(EJB_SUFFIX))
			componentName = base;
		else
			componentName = base + EJB_SUFFIX;
		setDefaultNestedComponentName(componentName, EJB);
		setProperty(EJB_COMPONENT_NAME, componentName);
		if (base.endsWith(WEB_SUFFIX))
			componentName = base;
		else
			componentName = base + WEB_SUFFIX;
		setDefaultNestedComponentName(componentName, WEB);
		setProperty(WEB_COMPONENT_NAME, componentName);
		if (base.endsWith(CLIENT_SUFFIX))
			componentName = base;
		else
			componentName = base + CLIENT_SUFFIX;
		setDefaultNestedComponentName(componentName, CLIENT);
		setProperty(APPCLIENT_COMPONENT_NAME, componentName);
		if (base.endsWith(CONNECTOR_SUFFIX))
			componentName = base;
		else
			componentName = base + CONNECTOR_SUFFIX;
		setDefaultNestedComponentName(componentName, RAR);
		setProperty(CONNECTOR_COMPONENT_NAME, componentName);
		
		
		// update the EAR Project Name field as well
		if(webModel != null){
			webModel.setProperty(IJ2EEFacetProjectCreationDataModelProperties.EAR_PROJECT_NAME, base);
		}
		if(clientModel != null){
			clientModel.setProperty(IJ2EEFacetProjectCreationDataModelProperties.EAR_PROJECT_NAME, base);
		}
		if(ejbModel != null){
			ejbModel.setProperty(IJ2EEFacetProjectCreationDataModelProperties.EAR_PROJECT_NAME, base);
		}
		if(jcaModel != null){
			jcaModel.setProperty(IJ2EEFacetProjectCreationDataModelProperties.EAR_PROJECT_NAME, base);
		}
	}

	private void setNestedJ2EEVersion(Object j2eeVersion) {
		int j2eeVer = ((Integer) j2eeVersion).intValue();
		if (ejbModel != null && ejbFacetModel != null) {
			String facetVersionString = J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToEJBVersionID(j2eeVer));
			IProjectFacetVersion facetVersion = ProjectFacetsManager.getProjectFacet(ejbFacetModel.getStringProperty(IFacetDataModelProperties.FACET_ID)).getVersion(facetVersionString);
			ejbFacetModel.setProperty(IFacetDataModelProperties.FACET_VERSION, facetVersion);
			//[Bug 243226] IFacetedProjectWorkingCopy facet version is not automatically updated so it has to be done manually
			IFacetedProjectWorkingCopy fpwc = (IFacetedProjectWorkingCopy)ejbModel.getProperty(IFacetProjectCreationDataModelProperties.FACETED_PROJECT_WORKING_COPY);
			fpwc.changeProjectFacetVersion(facetVersion);
		}
		if (webModel != null &&webFacetModel != null) {
			String facetVersionString = J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToWebVersionID(j2eeVer));
			IProjectFacetVersion facetVersion = ProjectFacetsManager.getProjectFacet(webFacetModel.getStringProperty(IFacetDataModelProperties.FACET_ID)).getVersion(facetVersionString);
			webFacetModel.setProperty(IFacetDataModelProperties.FACET_VERSION, facetVersion);
			//[Bug 243226] IFacetedProjectWorkingCopy facet version is not automatically updated so it has to be done manually
			IFacetedProjectWorkingCopy fpwc = (IFacetedProjectWorkingCopy)webModel.getProperty(IFacetProjectCreationDataModelProperties.FACETED_PROJECT_WORKING_COPY);
			fpwc.changeProjectFacetVersion(facetVersion);
		}
		if (jcaModel != null && jcaFacetModel != null) {
			String facetVersionString = J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToConnectorVersionID(j2eeVer));
			IProjectFacetVersion facetVersion = ProjectFacetsManager.getProjectFacet(jcaFacetModel.getStringProperty(IFacetDataModelProperties.FACET_ID)).getVersion(facetVersionString);
			jcaFacetModel.setProperty(IFacetDataModelProperties.FACET_VERSION, facetVersion);
			//[Bug 243226] IFacetedProjectWorkingCopy facet version is not automatically updated so it has to be done manually
			IFacetedProjectWorkingCopy fpwc = (IFacetedProjectWorkingCopy)jcaModel.getProperty(IFacetProjectCreationDataModelProperties.FACETED_PROJECT_WORKING_COPY);
			fpwc.changeProjectFacetVersion(facetVersion);
		}
		if (clientModel != null && clientFacetModel != null){
			String facetVersionString = J2EEVersionUtil.convertVersionIntToString(j2eeVer);
			IProjectFacetVersion facetVersion = ProjectFacetsManager.getProjectFacet(clientFacetModel.getStringProperty(IFacetDataModelProperties.FACET_ID)).getVersion(facetVersionString);
			clientFacetModel.setProperty(IFacetDataModelProperties.FACET_VERSION, facetVersion);
			//[Bug 243226] IFacetedProjectWorkingCopy facet version is not automatically updated so it has to be done manually
			IFacetedProjectWorkingCopy fpwc = (IFacetedProjectWorkingCopy)clientModel.getProperty(IFacetProjectCreationDataModelProperties.FACETED_PROJECT_WORKING_COPY);
			fpwc.changeProjectFacetVersion(facetVersion);
		}
	}

	private IDataModel getNestedModel(int flag) {
		switch (flag) {
			case EJB :
				return ejbModel;
			case WEB :
				return webModel;
			case RAR :
				return jcaModel;
			case CLIENT :
				return clientModel;
		}
		return null;
	}

	@Override
	public boolean isPropertyEnabled(String propertyName) {
		if (propertyName.equals(CREATE_CONNECTOR)) {
			int version = getIntProperty(J2EE_VERSION);
			return version > J2EEVersionConstants.J2EE_1_2_ID;
		}
		if( propertyName.equals(CONNECTOR_COMPONENT_NAME)){
			return getBooleanProperty(CREATE_CONNECTOR);
		}
		if (propertyName.equals(APPCLIENT_COMPONENT_NAME))
			return getBooleanProperty(CREATE_APPCLIENT);
		if (propertyName.equals(EJB_COMPONENT_NAME))
			return getBooleanProperty(CREATE_EJB);
		if (propertyName.equals(WEB_COMPONENT_NAME))
			return getBooleanProperty(CREATE_WEB);
		return super.isPropertyEnabled(propertyName);
	}
	
	@Override
	public void dispose() {
		for(IDataModel dm: extendedModelsToDispose){
			dm.dispose();
		}
		extendedModelsToDispose.clear();
		super.dispose();
	}
}
