/*******************************************************************************
 * Copyright (c) 2003, 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
 *******************************************************************************/
package org.eclipse.jst.j2ee.application.internal.operations;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.common.project.facet.core.JavaFacet;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.SaveFilter;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.datamodel.properties.IJ2EEComponentImportDataModelProperties;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.archive.ArchiveWrapper;
import org.eclipse.jst.j2ee.internal.archive.JavaEEArchiveUtilities;
import org.eclipse.jst.j2ee.internal.project.J2EECreationResourceHandler;
import org.eclipse.jst.jee.archive.ArchiveOpenFailureException;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.datamodel.FacetProjectCreationDataModelProvider;
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.DataModelEvent;
import org.eclipse.wst.common.frameworks.datamodel.DataModelPropertyDescriptor;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelListener;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonMessages;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
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.runtime.IRuntime;

public abstract class J2EEArtifactImportDataModelProvider extends AbstractDataModelProvider implements IJ2EEComponentImportDataModelProperties, IDataModelListener {

	private static final String USE_DEFAULT_PROJECT_NAME = "J2EEArtifactImportDataModelProvider.USE_DEFAULT_PROJECT_NAME"; //$NON-NLS-1$
	
	public static final String FACET_RUNTIME = "IJ2EEArtifactImportDataModelProperties.FACET_RUNTIME"; //$NON-NLS-1$	

	private IDataModel componentCreationDM;
	private Throwable archiveOpenFailure = null;

	public Set getPropertyNames() {
		Set propertyNames = super.getPropertyNames();
		propertyNames.add(FILE_NAME);
		propertyNames.add(FILE);
		propertyNames.add(SAVE_FILTER);
		propertyNames.add(OVERWRITE_HANDLER);
		propertyNames.add(CLOSE_ARCHIVE_ON_DISPOSE);
		propertyNames.add(USE_DEFAULT_PROJECT_NAME);
		propertyNames.add(PROJECT_NAME);
		propertyNames.add(COMPONENT);
		propertyNames.add( FACET_RUNTIME );
		propertyNames.add(ARCHIVE_WRAPPER);
		return propertyNames;
	}

	public void init() {
		super.init();
		componentCreationDM = createJ2EEComponentCreationDataModel();
		componentCreationDM.setBooleanProperty(FacetProjectCreationDataModelProvider.FORCE_VERSION_COMPLIANCE, false);
		componentCreationDM.addListener(this);
		model.addNestedModel(NESTED_MODEL_J2EE_COMPONENT_CREATION, componentCreationDM);
	}

	public Object getDefaultProperty(String propertyName) {
		if (propertyName.equals(CLOSE_ARCHIVE_ON_DISPOSE)) {
			return Boolean.TRUE;
		} else if (propertyName.equals(USE_DEFAULT_PROJECT_NAME)) {
			return Boolean.TRUE;
		}else if( propertyName.equals(COMPONENT)){
			String projectName = getStringProperty(PROJECT_NAME);
			IProject project = ProjectUtilities.getProject(projectName);
			return ComponentCore.createComponent(project);			
		}
		return super.getDefaultProperty(propertyName);
	}

	private boolean settingFileName = false;

	public boolean propertySet(String propertyName, Object propertyValue) {
		if (propertyName.equals(ARCHIVE_WRAPPER)) {
			if(propertyValue != null){
				if (!settingFileName) {
					setProperty(FILE_NAME, null);
				}
				updateDefaultComponentName();
			}
			return true;
		} else if(propertyName.equals(FILE)){
			if(propertyValue != null){
				if(!settingFileName) {
					ArchiveWrapper archiveWrapper = getArchiveWrapper();
					if(null == archiveWrapper || archiveWrapper.getCommonArchive() != propertyValue){
						archiveWrapper = new ArchiveWrapper((Archive)propertyValue);
						setProperty(ARCHIVE_WRAPPER, archiveWrapper);
					}
				}
			}
		} else if (propertyName.equals(SAVE_FILTER) && getArchiveWrapper() != null && getArchiveWrapper().getCommonArchive() != null) {
			getArchiveWrapper().getCommonArchive().setSaveFilter(getSaveFilter());
		} else if (FILE_NAME.equals(propertyName)) {
			try {
				archiveOpenFailure = null;
				handleArchiveSetup((String) propertyValue);
			} catch (OpenFailureException oe) {
				archiveOpenFailure = oe;
			} catch (ArchiveOpenFailureException e) {
				archiveOpenFailure = e;
			}
		} else if( COMPONENT.equals(propertyName)){
			throw new RuntimeException(propertyName + " should not be set."); //$NON-NLS-1$
		}else if (PROJECT_NAME.equals(propertyName)) {
			List nestedModels = new ArrayList(model.getNestedModels());
			IDataModel nestedModel = null;
			for (int i = 0; i < nestedModels.size(); i++) {
				nestedModel = (IDataModel) nestedModels.get(i);
				try {
					nestedModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, propertyValue);
				} catch (Exception e) {
					Logger.getLogger().logError(e);
				}
			}
		} else if( FACET_RUNTIME.equals( propertyName )){
			throw new RuntimeException(propertyName + " should not be set."); //$NON-NLS-1$
		}
		return true;
	}

	private boolean doingComponentUpdate;

	private void updateDefaultComponentName() {
		ArchiveWrapper wrapper = getArchiveWrapper();
		if (null != wrapper && getBooleanProperty(USE_DEFAULT_PROJECT_NAME)) {
			try {
				doingComponentUpdate = true;
				IPath path = wrapper.getPath();
				String defaultProjectName = path.segment(path.segmentCount() - 1);
				if (defaultProjectName.indexOf('.') > 0) {
					defaultProjectName = defaultProjectName.substring(0, defaultProjectName.lastIndexOf('.'));
				}
				setProperty(PROJECT_NAME, defaultProjectName);
			} finally {
				doingComponentUpdate = false;
			}

		}
	}

	private boolean handleArchiveSetup(String fileName) throws OpenFailureException, ArchiveOpenFailureException {
		try {
			settingFileName = true;
			ArchiveWrapper wrapper = getArchiveWrapper();
			if (wrapper!= null) {
				wrapper.close();
				setProperty(FILE, null);
				setProperty(ARCHIVE_WRAPPER, null);
			}
			String uri = getStringProperty(FILE_NAME);
			if (!archiveExistsOnFile())
				return false;
			wrapper = openArchiveWrapper(uri);
			if(wrapper != null){
				setProperty(ARCHIVE_WRAPPER, wrapper);
				if(wrapper.getCommonArchive() != null){
					setProperty(FILE, wrapper.getCommonArchive());
				}
			}
			return wrapper!= null;
		} finally {
			settingFileName = false;
		}

	}

	protected ArchiveWrapper openArchiveWrapper(String uri) throws OpenFailureException, ArchiveOpenFailureException{
		IArchive archive = null;
		IPath path = new Path(uri);
		archive = JavaEEArchiveUtilities.INSTANCE.openArchive(path);
		archive.getArchiveOptions().setOption(JavaEEArchiveUtilities.DISCRIMINATE_EJB_ANNOTATIONS, Boolean.TRUE);
		archive.setPath(path);
		JavaEEQuickPeek jqp = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive);
		
		if(jqp.getJavaEEVersion() == J2EEConstants.UNKNOWN && jqp.getType() == J2EEConstants.UNKNOWN){
			handleUnknownType(jqp);
		}
		
		return new ArchiveWrapper(archive);
	}
	/**
	 * This method allows subclasses to handle an unknown archive type.
	 * @param jqp
	 */
	protected void handleUnknownType(JavaEEQuickPeek jqp) {
	}

	protected abstract Archive openArchive(String uri) throws OpenFailureException;

	private boolean closeArchive() {
		if (null != getArchiveWrapper()) {
			getArchiveWrapper().close();
		}
		return true;
	}

	public IStatus validate(String propertyName) {
		if (FILE_NAME.equals(propertyName) && !isPropertySet(ARCHIVE_WRAPPER)) {
			String fileName = getStringProperty(propertyName);
			if (fileName == null || fileName.length() == 0) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.ARCHIVE_FILE_NAME_EMPTY_ERROR, new Object[]{ArchiveUtil.getModuleFileTypeName(getType())}));
			} else if (archiveOpenFailure != null) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(archiveOpenFailure.getMessage()));
			} else if (fileName != null && !archiveExistsOnFile()) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.FILE_DOES_NOT_EXIST_ERROR, new Object[]{ArchiveUtil.getModuleFileTypeName(getType())}));
			}
		} else if (NESTED_MODEL_J2EE_COMPONENT_CREATION.equals(propertyName) ) {
			return getDataModel().getNestedModel(NESTED_MODEL_J2EE_COMPONENT_CREATION).validate(true);
		} else if(FACET_RUNTIME.equals(propertyName)){
			return validateVersionSupportedByServer();
		}
		return OK_STATUS;
	}

	protected int getJ2EEVersion() {
		return 0;
	}

	protected abstract IDataModel createJ2EEComponentCreationDataModel();

	/*
	 * @see XMLResource#APP_CLIENT_TYPE
	 * @see XMLResource#APPLICATION_TYPE
	 * @see XMLResource#EJB_TYPE
	 * @see XMLResource#WEB_APP_TYPE
	 * @see XMLResource#RAR_TYPE
	 */
	protected abstract int getType();

	private boolean archiveExistsOnFile() {
		String jarName = (String) getProperty(FILE_NAME);
		if (jarName != null && jarName.length() > 0) {
			java.io.File file = new java.io.File(jarName);
			return file.exists() && !file.isDirectory();
		}
		return false;
	}

	public void dispose() {
		if (getBooleanProperty(CLOSE_ARCHIVE_ON_DISPOSE))
			closeArchive();
		super.dispose();
	}

	protected final void setArchiveFile(Archive archiveFile) {
		setProperty(FILE, archiveFile);
	}
	
	protected final ArchiveWrapper getArchiveWrapper(){
		return (ArchiveWrapper)getProperty(ARCHIVE_WRAPPER);
	}
	
	/**
	 * @deprecated
	 * @return use ARCHIVE_WRAPPER
	 */
	protected final Archive getArchiveFile() {
		return (Archive) getProperty(FILE);
	}

	protected final ArchiveOptions getArchiveOptions() {
		ArchiveOptions opts = new ArchiveOptions();
		opts.setIsReadOnly(true);
		return opts;
	}

	private SaveFilter getSaveFilter() {
		return (SaveFilter) getProperty(SAVE_FILTER);
	}

	public DataModelPropertyDescriptor[] getValidPropertyDescriptors(String propertyName) {
		return super.getValidPropertyDescriptors(propertyName);
	}

	public void propertyChanged(DataModelEvent event) {
		if (!doingComponentUpdate && event.getDataModel() == componentCreationDM && event.getPropertyName().equals(PROJECT_NAME) && getBooleanProperty(USE_DEFAULT_PROJECT_NAME)) {
			setBooleanProperty(USE_DEFAULT_PROJECT_NAME, false);
		}
		if( event.getDataModel() == componentCreationDM && event.getPropertyName().equals(IFacetProjectCreationDataModelProperties.FACET_RUNTIME)){
			model.notifyPropertyChange(FACET_RUNTIME, IDataModel.DEFAULT_CHG);
		}
	}
	
	/**
	 * Calling this method will fixup the JST facet version if it is incompatible with the selected runtime
	 * It should be called when the Server Runtime or the Archive properties are set.
	 * @return
	 */
	protected IStatus validateVersionSupportedByServer(){
		if( model.isPropertySet(ARCHIVE_WRAPPER) && model.isPropertySet(IFacetProjectCreationDataModelProperties.FACET_RUNTIME)){
			IDataModel projectModel = model.getNestedModel(NESTED_MODEL_J2EE_COMPONENT_CREATION);
			FacetDataModelMap map = (FacetDataModelMap) projectModel.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP);
			Collection projectFacets = (Collection)getProperty(FacetProjectCreationDataModelProvider.REQUIRED_FACETS_COLLECTION);
					
			IRuntime runtime = (IRuntime) getProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME);
			if(runtime != null){
				for(Iterator iterator = projectFacets.iterator(); iterator.hasNext();){
					IDataModel facetDataModel = map.getFacetDataModel(((IProjectFacet)iterator.next()).getId());
					IProjectFacetVersion facetVersion = (IProjectFacetVersion)facetDataModel.getProperty(IFacetDataModelProperties.FACET_VERSION);
					if(facetVersion.getProjectFacet().equals(JavaFacet.FACET)){
						Set set = Collections.singleton(facetVersion.getProjectFacet());
						try {
							Set correctSet = runtime.getDefaultFacets(set);
							IProjectFacetVersion correctVersion = null;
							Iterator correctVersions = correctSet.iterator();
							while(correctVersions.hasNext() && correctVersion == null){
								IProjectFacetVersion version = (IProjectFacetVersion)correctVersions.next();
								if(version.getProjectFacet().equals(JavaFacet.FACET)){
									correctVersion = version;
								}
							}
							
							if(correctVersion != null){
								if(!facetVersion.equals(correctVersion)){
									facetDataModel.setProperty(IFacetDataModelProperties.FACET_VERSION, correctVersion);
									facetVersion = correctVersion;
								}
							}
						} catch (CoreException e) {
							Logger.getLogger().logError(e);
						}
					}
				
					if(!runtime.supports(facetVersion)){
						return WTPCommonPlugin.createErrorStatus( J2EECreationResourceHandler.VERSION_NOT_SUPPORTED ); //$NON-NLS-1$
					}
				}
			}
		}
		return OK_STATUS;
	}
}