/***************************************************************************************************
 * 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.j2ee.application.operations;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.internal.resources.ProjectDescription;
import org.eclipse.core.internal.resources.ProjectDescriptionReader;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
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.Path;
import org.eclipse.jst.j2ee.applicationclient.creation.IApplicationClientNatureConstants;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile;
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.internal.archive.operations.IOverwriteHandler;
import org.eclipse.jst.j2ee.internal.earcreation.EARCreationResourceHandler;
import org.eclipse.jst.j2ee.internal.earcreation.IEARNatureConstants;
import org.eclipse.jst.j2ee.internal.project.IConnectorNatureConstants;
import org.eclipse.jst.j2ee.internal.project.IEJBNatureConstants;
import org.eclipse.jst.j2ee.internal.project.IWebNatureConstants;
import org.eclipse.jst.j2ee.internal.project.J2EENature;
import org.eclipse.wst.common.frameworks.internal.operations.ProjectCreationDataModel;
import org.eclipse.wst.common.frameworks.internal.operations.WTPOperationDataModel;
import org.eclipse.wst.common.frameworks.internal.operations.WTPOperationDataModelEvent;
import org.eclispe.wst.common.frameworks.internal.plugin.WTPCommonMessages;
import org.eclispe.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
import org.xml.sax.InputSource;


public abstract class J2EEImportDataModel extends WTPOperationDataModel {
	/**
	 * Required, type String
	 */
	public static final String FILE_NAME = "J2EEImportDataModel.FILE_NAME"; //$NON-NLS-1$
	/**
	 * Optional, type Archive, used when a file is available as an object rather than a url (i.e.
	 * using the FILE_NAME property will not work).
	 */
	public static final String FILE = "J2EEImportDataModel.FILE"; //$NON-NLS-1$
	/**
	 * Optional, type Boolean defaults to false
	 */
	public static final String OVERWRITE_PROJECT = "J2EEImportDataModel.OVERWRITE_PROJECT"; //$NON-NLS-1$
	/**
	 * Optional, type Boolean defaults to false
	 */
	public static final String DELETE_BEFORE_OVERWRITE_PROJECT = "J2EEImportDataModel.DELETE_BEFORE_OVERWRITE_PROJECT"; //$NON-NLS-1$
	/**
	 * Optional, type SaveFilter, default is null
	 */
	public static final String SAVE_FILTER = "J2EEImportDataModel.SAVE_FILTER"; //$NON-NLS-1$
	/**
	 * Optional, type Boolean, default false this is used only when importing modules in with an ear
	 */
	public static final String PRESERVE_PROJECT_METADATA = "J2EEImportDataModel.IS_LIBRARY"; //$NON-NLS-1$
	/**
	 * Do not set this property.
	 */
	public static final String BINARY = "J2EEImportDataModel.BINARY"; //$NON-NLS-1$
	public static final String OVERWRITE_HANDLER = "J2EEImportDataModel.OVERWRITE_HANDLER"; //$NON-NLS-1$
	public static final String PROJECT_NAME = "J2EEImportDataModel.PROJECT_NAME"; //$NON-NLS-1$
	public static final String NESTED_MODEL_J2EE_PROJECT_CREATION = "J2EEImportDataModel.NESTED_MODEL_J2EE_PROJECT_CREATION"; //$NON-NLS-1$
	/**
	 * Optional - Should the archive be closed on dispose?
	 * 
	 * @type - Boolean, default is True
	 */
	public static final String CLOSE_ARCHIVE_ON_DISPOSE = "J2EEImportDataModel.closeArchiveOnDispose"; //$NON-NLS-1$
	/**
	 * Optiona - type String, default = getArchiveFile().getURI() or "" if getArchivefile() is null
	 * This is used when adding a module to the ear.
	 */
	public static final String URI_FOR_MODULE_MAPPING = "J2EEImportDataModel.URI_FOR_MODULE_MAPPING"; //$NON-NLS-1$

	public static final String FILE_SELECTION_HISTORY = "J2EEImportDataModel.FILE_SELECTION_HISTORY"; //$NON-NLS-1$

	private static final String DEFAULT_PROJECT_NAME = "J2EEImportDataModel.DEFAULT_PROJECT_NAME"; //$NON-NLS-1$

	/**
	 * Extended attributes
	 */
	public static final String SERVER_TARGET_ID = J2EEProjectCreationDataModel.SERVER_TARGET_ID;
	protected J2EEProjectCreationDataModel j2eeProjectCreationDataModel;
	protected Archive moduleFile;
	protected OpenFailureException cachedOpenFailureException = null;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.internal.emfworkbench.operation.EditModelOperationDataModel#initValidBaseProperties()
	 */
	protected void initValidBaseProperties() {
		addValidBaseProperty(FILE_NAME);
		addValidBaseProperty(FILE);
		addValidBaseProperty(OVERWRITE_PROJECT);
		addValidBaseProperty(DELETE_BEFORE_OVERWRITE_PROJECT);
		addValidBaseProperty(SAVE_FILTER);
		addValidBaseProperty(PRESERVE_PROJECT_METADATA);
		addValidBaseProperty(BINARY);
		addValidBaseProperty(OVERWRITE_HANDLER);
		addValidBaseProperty(PROJECT_NAME);
		addValidBaseProperty(CLOSE_ARCHIVE_ON_DISPOSE);
		addValidBaseProperty(URI_FOR_MODULE_MAPPING);
		addValidBaseProperty(FILE_SELECTION_HISTORY);
		addValidBaseProperty(DEFAULT_PROJECT_NAME);
		super.initValidBaseProperties();
	}

	protected void initNestedModels() {
		super.initNestedModels();
		j2eeProjectCreationDataModel = createJ2EEProjectCreationDataModel();
		j2eeProjectCreationDataModel.setBooleanProperty(J2EEProjectCreationDataModel.CREATE_DEFAULT_FILES, false);
		j2eeProjectCreationDataModel.addListener(this);
		addNestedModel(NESTED_MODEL_J2EE_PROJECT_CREATION, j2eeProjectCreationDataModel);
	}

	protected Object getDefaultProperty(String propertyName) {
		if (propertyName.equals(BINARY)) {
			return getProperty(PRESERVE_PROJECT_METADATA);
		}
		if (propertyName.equals(PRESERVE_PROJECT_METADATA) || propertyName.equals(OVERWRITE_PROJECT) || propertyName.equals(DELETE_BEFORE_OVERWRITE_PROJECT)) {
			return Boolean.FALSE;
		} else if (propertyName.equals(PROJECT_NAME)) {
			return j2eeProjectCreationDataModel.getProperty(J2EEProjectCreationDataModel.PROJECT_NAME);
		} else if (propertyName.equals(CLOSE_ARCHIVE_ON_DISPOSE)) {
			return Boolean.TRUE;
		} else if (propertyName.equals(URI_FOR_MODULE_MAPPING)) {
			if (null == getArchiveFile()) {
				return ""; //$NON-NLS-1$
			}
			return getArchiveFile().getURI();
		} else if (propertyName.equals(DEFAULT_PROJECT_NAME)) {
			return Boolean.TRUE;
		}
		return super.getDefaultProperty(propertyName);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModel#doSetProperty(java.lang.String,
	 *      java.lang.Object)
	 */
	protected boolean doSetProperty(String propertyName, Object propertyValue) {
		if (propertyName.equals(BINARY)) {
			throw new RuntimeException("Property " + BINARY + " may not be set."); //$NON-NLS-1$  //$NON-NLS-2$
		}
		if (propertyName.equals(FILE)) {
			setProperty(FILE_NAME, null);
			super.doSetProperty(propertyName, propertyValue);
			moduleFile = (Archive) propertyValue;
			updateDefaultProjectName();
			return true;
		}
		boolean doSet = super.doSetProperty(propertyName, propertyValue);
		if (propertyName.equals(FILE_SELECTION_HISTORY)) {
			notifyValidValuesChange(FILE_NAME);
		}

		if (propertyName.equals(PRESERVE_PROJECT_METADATA) && forceResetOnPreserveMetaData()) {
			if (getBooleanProperty(PRESERVE_PROJECT_METADATA) && null != getArchiveFile()) {
				if (getArchiveFile().containsFile(ProjectDescription.DESCRIPTION_FILE_NAME)) {
					try {
						File dotProject = getArchiveFile().getFile(ProjectDescription.DESCRIPTION_FILE_NAME);
						ProjectDescriptionReader reader = new ProjectDescriptionReader();
						ProjectDescription description = reader.read(new InputSource(dotProject.getInputStream()));
						setProperty(PROJECT_NAME, description.getName());
					} catch (FileNotFoundException e) {
					} catch (IOException e) {
					}
				}
			}
		}

		//		if (propertyName.equals(PRESERVE_PROJECT_METADATA) && forceResetOnPreserveMetaData() &&
		// isSet(PROJECT_NAME)) {
		//				if (null != moduleFile) {
		//				
		//				
		//				Path path = new Path(moduleFile.getURI());
		//				String defaultProjectName = path.segment(path.segmentCount() - 1);
		//				if (defaultProjectName.indexOf(".") > 0) { //$NON-NLS-1$
		//					defaultProjectName = defaultProjectName.substring(0, defaultProjectName.indexOf("."));
		// //$NON-NLS-1$
		//				}
		//				if (!getBooleanProperty(PRESERVE_PROJECT_METADATA)) {
		//					String baseName = defaultProjectName;
		//					IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		//					for (int i = 1; i < 10 && root.getProject(defaultProjectName).exists(); i++) {
		//						defaultProjectName = baseName + Integer.toString(i);
		//					}
		//				}
		//				setProperty(PROJECT_NAME, defaultProjectName);
		//			}
		//		}
		//        if (propertyName.equals(OVERWRITE_PROJECT)) {
		//            updateDefaultProjectName();
		//        }
		if (propertyName.equals(PROJECT_NAME)) {
			j2eeProjectCreationDataModel.setProperty(J2EEProjectCreationDataModel.PROJECT_NAME, propertyValue);
		} else if (propertyName.equals(SAVE_FILTER) && moduleFile != null) {
			moduleFile.setSaveFilter(getSaveFilter());
		}
		if (doSet) {
			if (FILE_NAME.equals(propertyName)) {
				boolean success = false;
				try {
					cachedOpenFailureException = null;
					success = handleArchiveSetup((String) propertyValue);
				} catch (OpenFailureException oe) {
					cachedOpenFailureException = oe;
				}
				if (success)
					updateDefaultProjectName();
			}
		}
		return doSet;
	}

	protected boolean forceResetOnPreserveMetaData() {
		return true;
	}

	private void updateDefaultProjectName() {
		if (null != moduleFile && getBooleanProperty(DEFAULT_PROJECT_NAME)) {
			Path path = new Path(moduleFile.getURI());
			String defaultProjectName = path.segment(path.segmentCount() - 1);
			if (defaultProjectName.indexOf(".") > 0) { //$NON-NLS-1$
				defaultProjectName = defaultProjectName.substring(0, defaultProjectName.indexOf(".")); //$NON-NLS-1$
			}
			if (!getBooleanProperty(OVERWRITE_PROJECT)) {
				String baseName = defaultProjectName;
				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
				for (int i = 1; i < 10 && root.getProject(defaultProjectName).exists(); i++) {
					defaultProjectName = baseName + Integer.toString(i);
				}
			}
			j2eeProjectCreationDataModel.setProperty(J2EEProjectCreationDataModel.PROJECT_NAME, defaultProjectName);
			notifyDefaultChange(PROJECT_NAME);
			setBooleanProperty(DEFAULT_PROJECT_NAME, true);
		}
	}

	private boolean handleArchiveSetup(String fileName) throws OpenFailureException {
		boolean archiveStatus = true;
		if (moduleFile != null) {
			moduleFile.close();
			moduleFile = null;
		}
		String uri = getStringProperty(FILE_NAME);
		if (!archiveExistsOnFile())
			return false;
		archiveStatus = openArchive(uri);
		moduleFile.setSaveFilter(getSaveFilter());
		return archiveStatus;
	}

	protected abstract boolean openArchive(String uri) throws OpenFailureException;

	protected boolean closeModuleFile() {
		if (null != moduleFile) {
			moduleFile.close();
			moduleFile = null;
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModel#doValidateProperty(java.lang.String)
	 */
	protected IStatus doValidateProperty(String propertyName) {
		if (NESTED_MODEL_VALIDATION_HOOK.equals(propertyName)) {
			return OK_STATUS;
		}
		if (PROJECT_NAME.equals(propertyName)) {
			IStatus status = validateProjectName(j2eeProjectCreationDataModel.projectDataModel.getStringProperty(ProjectCreationDataModel.PROJECT_NAME));
			if (!status.isOK()) {
				return status;
			}
			IProject project = j2eeProjectCreationDataModel.projectDataModel.getProject();
			if (null != project && !project.exists() || !getBooleanProperty(OVERWRITE_PROJECT)) {
				status = j2eeProjectCreationDataModel.projectDataModel.validateDataModel();
				if (!status.isOK()) {
					status = WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.getString("EARImportDataModel_UI_3", new Object[]{project.getName()}));//$NON-NLS-1$
				}
				return status;
			}
			if (!getBooleanProperty(DELETE_BEFORE_OVERWRITE_PROJECT)) {
				//now we have an existing project we are going to overwrite
				String[] natures = (String[]) j2eeProjectCreationDataModel.projectDataModel.getProperty(ProjectCreationDataModel.PROJECT_NATURES);
				for (int i = 0; null != natures && i < natures.length; i++) {
					try {
						if (!project.hasNature(natures[i])) {
							return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.getString("importWrongType", new Object[]{project.getName()}));//$NON-NLS-1$
						}
					} catch (CoreException e) {
					}
				}
				J2EENature nature = J2EENature.getRegisteredRuntime(project);
				if (null != nature && nature.getJ2EEVersion() < getJ2EEVersion()) {
					return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.getString("importWrongVersion", new Object[]{project.getName()}));//$NON-NLS-1$
				}
			} else {
				String name = getStringProperty(PROJECT_NAME);
				IWorkspace workspace = ResourcesPlugin.getWorkspace();
				return workspace.validateName(name, IResource.PROJECT);
			}
			return OK_STATUS;
		}
		if (FILE_NAME.equals(propertyName)) {
			String fileName = (String) getProperty(FILE_NAME);
			if (fileName != null && fileName.equals("")) { //$NON-NLS-1$
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.ARCHIVE_FILE_NAME_EMPTY_ERROR, new Object[]{ArchiveUtil.getModuleFileTypeName(getType())})); //$NON-NLS-1$);
			} else if (cachedOpenFailureException != null) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(cachedOpenFailureException.getMessage())); //$NON-NLS-1$);
			} else if (fileName != null && !archiveExistsOnFile()) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.FILE_DOES_NOT_EXIST_ERROR, new Object[]{ArchiveUtil.getModuleFileTypeName(getType())}));
			}
		}
		return super.doValidateProperty(propertyName);
	}

	protected int getJ2EEVersion() {
		return 0;
	}

	protected abstract J2EEProjectCreationDataModel createJ2EEProjectCreationDataModel();

	/*
	 * @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();

	public J2EEProjectCreationDataModel getJ2eeProjectCreationDataModel() {
		return j2eeProjectCreationDataModel;
	}

	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))
			closeModuleFile();
		super.dispose();
	}

	public Archive getArchiveFile() {
		return moduleFile;
	}

	public ModuleFile getModuleFile() {
		return (ModuleFile) moduleFile;
	}

	public IProject getProject() {
		return j2eeProjectCreationDataModel.getTargetProject();
	}

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

	public IOverwriteHandler getOverwriteHandler() {
		return (IOverwriteHandler) getProperty(OVERWRITE_HANDLER);
	}

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

	public void propertyChanged(WTPOperationDataModelEvent event) {
		if (event.getDataModel().equals(j2eeProjectCreationDataModel) && event.getPropertyName().equals(J2EEProjectCreationDataModel.PROJECT_NAME)) {
			setProperty(PROJECT_NAME, j2eeProjectCreationDataModel.getStringProperty(J2EEProjectCreationDataModel.PROJECT_NAME));
			setBooleanProperty(DEFAULT_PROJECT_NAME, false);
		}
		super.propertyChanged(event);
	}

	public void extractHandled(List newList, boolean addModels) {
	}

	protected Object[] doGetValidPropertyValues(String propertyName) {
		if (propertyName.equals(PROJECT_NAME)) {
			int j2eeVersion = getJ2EEVersion();
			IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
			ArrayList projectList = new ArrayList();
			String[] natureIds = (String[]) j2eeProjectCreationDataModel.projectDataModel.getProperty(ProjectCreationDataModel.PROJECT_NATURES);
			String j2eeNatureID = null;
			for (int j = 0; null == j2eeNatureID && j < natureIds.length; j++) {
				if (IEARNatureConstants.NATURE_ID.equals(natureIds[j]) || IEJBNatureConstants.NATURE_ID.equals(natureIds[j]) || IWebNatureConstants.J2EE_NATURE_ID.equals(natureIds[j]) || IConnectorNatureConstants.NATURE_ID.equals(natureIds[j]) || IApplicationClientNatureConstants.NATURE_ID.equals(natureIds[j])) {
					j2eeNatureID = natureIds[j];
				}
			}
			J2EENature j2eeNature = null;
			for (int i = 0; i < projects.length && j2eeNatureID != null; i++) {
				try {
					j2eeNature = (J2EENature) projects[i].getNature(j2eeNatureID);
					if (j2eeNature != null) {
						if (j2eeVersion <= j2eeNature.getJ2EEVersion()) {
							projectList.add(projects[i].getName());
						}
					}
				} catch (CoreException e) {
				}
			}
			String[] projectNames = new String[projectList.size()];
			for (int i = 0; i < projectNames.length; i++) {
				projectNames[i] = (String) projectList.get(i);
			}
			return projectNames;
		} else if (propertyName.equals(FILE_NAME)) {
			String[] sourceNames = (String[]) getProperty(FILE_SELECTION_HISTORY);
			return sourceNames;
		}
		return super.doGetValidPropertyValues(propertyName);
	}
}