/*******************************************************************************
 * Copyright (c) 2007, 2008 SAP AG 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:
 * Kaloyan Raev, kaloyan.raev@sap.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.web.operations;

import static org.eclipse.jst.j2ee.application.internal.operations.IAnnotationsDataModel.USE_ANNOTATIONS;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.CLASS_NAME;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.CONSTRUCTOR;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_ABSTRACT;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_PUBLIC;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SOURCE_FOLDER;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SUPERCLASS;
import static org.eclipse.jst.j2ee.internal.web.operations.INewWebClassDataModelProperties.DESCRIPTION;
import static org.eclipse.jst.j2ee.internal.web.operations.INewWebClassDataModelProperties.DISPLAY_NAME;
import static org.eclipse.jst.j2ee.internal.web.operations.INewWebClassDataModelProperties.JAVA_EE_VERSION;
import static org.eclipse.jst.j2ee.internal.web.operations.INewWebClassDataModelProperties.REGISTER_IN_WEB_XML;
import static org.eclipse.jst.j2ee.internal.web.operations.INewWebClassDataModelProperties.USE_EXISTING_CLASS;

import java.io.File;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.application.internal.operations.IAnnotationsDataModel;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.common.operations.NewJavaClassDataModelProvider;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
import org.eclipse.wst.common.componentcore.internal.util.FacetedProjectUtilities;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;

/**
 * The NewWebClassDataModelProvider is a subclass of
 * NewJavaClassDataModelProvider and follows the IDataModel Operation and Wizard
 * frameworks.
 * 
 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider
 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation
 * 
 * This data model provider is a subclass of the NewJavaClassDataModelProvider,
 * which stores base properties necessary in the creation of a default java
 * class.
 * @see org.eclipse.jst.j2ee.internal.common.operations.NewJavaClassDataModelProvider
 * 
 * The NewWebClassDataModelProvider provides more specific properties for java
 * class creation that are required in creating a web artifact java class. The
 * data model provider is used to store these values for the
 * AddWebClassOperation.
 * @see org.eclipse.jst.j2ee.internal.web.operations.INewWebClassDataModelProperties
 *      That operation will create the web artifact java class based on the
 *      settings defined here in the data model.
 * @see org.eclipse.jst.j2ee.internal.web.operations.AddWebClassOperation
 * 
 * This data model properties implements the IAnnotationsDataModel to get the
 * USE_ANNOTATIONS property for determining whether or not to generate an
 * annotated java class.
 * @see org.eclipse.jst.j2ee.application.internal.operations.IAnnotationsDataModel
 * 
 * Clients can subclass this data model provider to cache and provide their own
 * specific attributes. They should also provide their own validation methods,
 * properties interface, and default values for the properties they add.
 * 
 * The use of this class is EXPERIMENTAL and is subject to substantial changes.
 */
public abstract class NewWebClassDataModelProvider extends NewJavaClassDataModelProvider  {
	
	/**
	 * The fully qualified default superclass.
	 */
	private final static String DEFAULT_SUPERCLASS = ""; //$NON-NLS-1$ 

	/**
	 * The cache of all the interfaces the web artifact java class will
	 * implement.
	 */
	protected List interfaceList;
	
	private String classNameCache;
	private String existingClassNameCache;

	private static boolean useAnnotations = false;
	
	/**
	 * Subclasses may extend this method to provide their own determination of
	 * whether or not certain properties should be disabled or enabled. This
	 * method does not accept null parameter. It will not return null. This
	 * implementation makes sure annotation support is only allowed on web
	 * projects of J2EE version 1.3 or higher.
	 * 
	 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider#isPropertyEnabled(String)
	 * @see IAnnotationsDataModel#USE_ANNOTATIONS
	 * 
	 * @param propertyName
	 * @return boolean should property be enabled?
	 */
	@Override
	public boolean isPropertyEnabled(String propertyName) {
		// Annotations should only be enabled on a valid j2ee project of version 1.3 or higher
		if (USE_ANNOTATIONS.equals(propertyName)) {
			return !getBooleanProperty(USE_EXISTING_CLASS) && isAnnotationsSupported();
		} else if (MODIFIER_PUBLIC.equals(propertyName)) {
			return false;
		} else if (MODIFIER_ABSTRACT.equals(propertyName)) {
			return false;
		} else if (CONSTRUCTOR.equals(propertyName)) {
			return hasSuperClass();
		}
		// Otherwise return super implementation
		return super.isPropertyEnabled(propertyName);
	}

	/**
	 * Subclasses may extend this method to add their own data model's
	 * properties as valid base properties.
	 * 
	 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider#getPropertyNames()
	 */
	@Override
	public Set getPropertyNames() {
		// Add web artifact specific properties defined in this data model
		Set propertyNames = super.getPropertyNames();
		propertyNames.add(REGISTER_IN_WEB_XML);
		propertyNames.add(DISPLAY_NAME);
		propertyNames.add(DESCRIPTION);
		propertyNames.add(USE_EXISTING_CLASS);
		propertyNames.add(USE_ANNOTATIONS);
		propertyNames.add(JAVA_EE_VERSION);
		
		return propertyNames;
	}

	/**
	 * Subclasses may extend this method to provide their own default values for
	 * any of the properties in the data model hierarchy. This method does not
	 * accept a null parameter. It may return null. This implementation sets
	 * annotation use to be true.
	 * 
	 * @see NewJavaClassDataModelProvider#getDefaultProperty(String)
	 * @see IDataModelProvider#getDefaultProperty(String)
	 * 
	 * @param propertyName
	 * @return Object default value of property
	 */
	@Override
	public Object getDefaultProperty(String propertyName) {
		if (propertyName.equals(DISPLAY_NAME))
			return Signature.getSimpleName(getStringProperty(CLASS_NAME));
		else if (propertyName.equals(USE_ANNOTATIONS))
			return shouldDefaultAnnotations();
		else if (propertyName.equals(SUPERCLASS))
			return DEFAULT_SUPERCLASS;
		else if (propertyName.equals(USE_EXISTING_CLASS))
			return Boolean.FALSE;
		else if (propertyName.equals(CONSTRUCTOR))
			return hasSuperClass();
		else if (propertyName.equals(REGISTER_IN_WEB_XML)){
			return !isJavaEE6Project();
		} else if (JAVA_EE_VERSION.equals(propertyName)){
			return getJavaEEVersion();
		}
		// Otherwise check super for default value for property
		return super.getDefaultProperty(propertyName);
	}

	@SuppressWarnings("restriction")
	public boolean isJavaEE6Project() {
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(getStringProperty(PROJECT_NAME));
		if (project != null && project.isAccessible()){
			try {
				return (FacetedProjectFramework.hasProjectFacet(project, WebFacetUtils.WEB_FACET.getId(), WebFacetUtils.WEB_30.getVersionString())
						|| FacetedProjectFramework.hasProjectFacet(project, WebFacetUtils.WEBFRAGMENT_FACET.getId(), WebFacetUtils.WEBFRAGMENT_30.getVersionString()));
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
	
	@SuppressWarnings("restriction")
	public String getJavaEEVersion() {
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(getStringProperty(PROJECT_NAME));
		String id = null;
		if(JavaEEProjectUtilities.isDynamicWebProject(project)){
			id = WebFacetUtils.WEB_FACET.getId();
		}else {
			id = WebFacetUtils.WEBFRAGMENT_FACET.getId();
		}
		return FacetedProjectUtilities.getProjectFacetVersion(project, id).getVersionString();
	}

	/**
	 * Subclasses may extend this method to add their own specific behavior when
	 * a certain property in the data model hierarchy is set. this method does
	 * not accept null for the property name, but it will for propertyValue. It
	 * will not return null. It will return false if the set fails. This
	 * implementation verifies the display name is set to the class name, that
	 * the annotations is disabled/enabled properly, and that the target project
	 * name is determined from the source folder setting.
	 * 
	 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider#propertySet(String,
	 *      Object)
	 * 
	 * @param propertyName
	 * @param propertyValue
	 * @return boolean was property set?
	 */
	@Override
	public boolean propertySet(String propertyName, Object propertyValue) {
		// If annotations is changed, notify an enablement change
		if (propertyName.equals(USE_ANNOTATIONS)) {
			useAnnotations = ((Boolean) propertyValue).booleanValue();
			if (useAnnotations && !isAnnotationsSupported())
				return true;
			model.notifyPropertyChange(USE_ANNOTATIONS, IDataModel.ENABLE_CHG);
		}
		// If the source folder is changed, ensure we have the correct project name
		if (propertyName.equals(SOURCE_FOLDER)) {
			// Get the project name from the source folder name
			String sourceFolder = (String) propertyValue;
			int index = sourceFolder.indexOf(File.separator);
			String projectName = sourceFolder;
			if (index == 0)
				projectName = sourceFolder.substring(1);
			index = projectName.indexOf(File.separator);
			if (index != -1) {
				projectName = projectName.substring(0, index);
				setProperty(PROJECT_NAME, projectName);
			}
		}
		// Call super to set the property on the data model
		boolean result = super.propertySet(propertyName, propertyValue);
		// If class name is changed, update the display name to be the same
		if (propertyName.equals(CLASS_NAME) && !model.isPropertySet(DISPLAY_NAME)) {
			model.notifyPropertyChange(DISPLAY_NAME, IDataModel.DEFAULT_CHG);
		}
		// After the property is set, if project changed, update the nature and the annotations
		// enablement
		if (propertyName.equals(COMPONENT_NAME)) {
			model.notifyPropertyChange(USE_ANNOTATIONS, IDataModel.ENABLE_CHG);
		}
		// After property is set, if annotations is set to true, update its value based on the new
		// level of the project
		if (getBooleanProperty(USE_ANNOTATIONS)) {
			if (!isAnnotationsSupported())
				setBooleanProperty(USE_ANNOTATIONS, false);
		}
		if (propertyName.equals(USE_EXISTING_CLASS)) {
			model.notifyPropertyChange(USE_ANNOTATIONS, IDataModel.ENABLE_CHG);
			
			if (((Boolean) propertyValue).booleanValue()) {
				classNameCache = getStringProperty(CLASS_NAME);
				setProperty(CLASS_NAME, existingClassNameCache);
			} else {
				existingClassNameCache = getStringProperty(CLASS_NAME);
				setProperty(CLASS_NAME, classNameCache);
			}
		}
		// if super class is changed, notify the constructor checkbox to update
		// its enabled state
		if (SUPERCLASS.equals(propertyName)) {
			model.notifyPropertyChange(CONSTRUCTOR, IDataModel.ENABLE_CHG);
			if (!hasSuperClass()) {
				model.setProperty(CONSTRUCTOR, null);
			}
			model.notifyPropertyChange(CONSTRUCTOR, IDataModel.DEFAULT_CHG);
		}
		
		// Return whether property was set
		return result;
	}

	/**
	 * This method is used to determine if annotations should try to enable
	 * based on workspace settings
	 * 
	 * @return does any valid annotation provider or xdoclet handler exist
	 */
	//TODO add this method back in for defect 146696
//	protected boolean isAnnotationProviderDefined() {
//		boolean isControllerEnabled = AnnotationsControllerManager.INSTANCE.isAnyAnnotationsSupported();
//		final String preferred = AnnotationPreferenceStore.getProperty(AnnotationPreferenceStore.ANNOTATIONPROVIDER);
//		IAnnotationProvider annotationProvider = null;
//		boolean isProviderEnabled = false;
//		if (preferred != null) {
//			try {
//				annotationProvider = AnnotationUtilities.findAnnotationProviderByName(preferred);
//			} catch (Exception ex) { 
//				//Default
//			}
//			if (annotationProvider != null && annotationProvider.isValid())
//				isProviderEnabled = true;
//		}
//		return isControllerEnabled || isProviderEnabled;
//	}
	
	/**
	 * This method checks to see if valid annotation providers exist and if
	 * valid project version levels exist.
	 * 
	 * @return should annotations be supported for this project in this
	 *         workspace
	 */
	protected boolean isAnnotationsSupported() {
		//TODO add this check back in for defect 146696
//		if (!isAnnotationProviderDefined())
//			return false;
		if (!model.isPropertySet(PROJECT_NAME))
			return true;
		if (getStringProperty(PROJECT_NAME).equals("")) //$NON-NLS-1$
			return true;
		IProject project = ProjectUtilities.getProject(getStringProperty(PROJECT_NAME));
		String moduleName = getStringProperty(COMPONENT_NAME);
		if (project == null || moduleName == null || moduleName.equals(""))return true; //$NON-NLS-1$
		int j2eeVersion = J2EEVersionUtil.convertVersionStringToInt(J2EEProjectUtilities.getJ2EEProjectVersion(project));
		
		return j2eeVersion > J2EEVersionConstants.VERSION_1_2;
		
	}

	/**
	 * Subclasses may extend this method to provide their own validation on any
	 * of the valid data model properties in the hierarchy. It does not accept a
	 * null parameter. This method will not return null.
	 * 
	 * @see NewJavaClassDataModelProvider#validate(String)
	 * 
	 * @param propertyName
	 * @return IStatus is property value valid?
	 */
	@Override
	public IStatus validate(String propertyName) {
		if (propertyName.equals(SUPERCLASS)) {
			// If our default is the superclass, we know it is ok
			if (getStringProperty(propertyName).equals(DEFAULT_SUPERCLASS))			
				return WTPCommonPlugin.OK_STATUS;
		}
		
		if (propertyName.equals(CLASS_NAME)) {
			if (getStringProperty(propertyName).length() !=0 && getBooleanProperty(USE_EXISTING_CLASS)) {
				return WTPCommonPlugin.OK_STATUS;
			}
		}
		
		// Otherwise defer to super to validate the property
		return super.validate(propertyName);
	}
	
	/**
	 * This method is intended for internal use only. It provides a simple
	 * algorithm for detecting if there are duplicate entries in a list. It will
	 * accept a null parameter. It will not return null.
	 * 
	 * @see NewWebClassDataModelProvider#validateInitParamList(List)
	 * @see NewWebClassDataModelProvider#validateURLMappingList(List)
	 * 
	 * @param input
	 * @return boolean are there dups in the list?
	 */
	protected boolean hasDuplicatesInStringArrayList(List input) {
		// If list is null or empty return false
		if (input == null)
			return false;
		int n = input.size();
		boolean dup = false;
		// nested for loops to check each element to see if other elements are the same
		for (int i = 0; i < n; i++) {
			String[] sArray1 = (String[]) input.get(i);
			for (int j = i + 1; j < n; j++) {
				String[] sArray2 = (String[]) input.get(j);
				if (isTwoStringArraysEqual(sArray1, sArray2)) {
					dup = true;
					break;
				}
			}
			if (dup)
				break;
		}
		// Return boolean status for duplicates
		return dup;
	}

	/**
	 * This method is intended for internal use only. This checks to see if the
	 * two string arrays are equal. If either of the arrays are null or empty,
	 * it returns false.
	 * 
	 * @see NewWebClassDataModelProvider#hasDuplicatesInStringArrayList(List)
	 * 
	 * @param sArray1
	 * @param sArray2
	 * @return boolean are Arrays equal?
	 */
	protected boolean isTwoStringArraysEqual(String[] sArray1, String[] sArray2) {
		// If either array is null, return false
		if (sArray1 == null || sArray2 == null)
			return false;
		int n1 = sArray1.length;
		int n2 = sArray1.length;
		// If either array is empty, return false
		if (n1 == 0 || n2 == 0)
			return false;
		// If they don't have the same length, return false
		if (n1 != n2)
			return false;
		// If their first elements do not match, return false
		if (!sArray1[0].equals(sArray2[0]))
			return false;
		// Otherwise return true
		return true;
	}

	protected boolean hasSuperClass() {
		String superClass = model.getStringProperty(SUPERCLASS);
		return (superClass == null) ? false : superClass.trim().length() > 0;
	}

	/**
	 * @return boolean should the default annotations be true?
	 */
	private static Boolean shouldDefaultAnnotations() {
		if (useAnnotations)
			return Boolean.TRUE;
		return Boolean.FALSE;
	}
	
}
