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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
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.jst.j2ee.archive.IArchiveExportParticipant;
import org.eclipse.jst.j2ee.datamodel.properties.IJ2EEComponentExportDataModelProperties;
import org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelProvider;
import org.eclipse.wst.common.frameworks.datamodel.DataModelPropertyDescriptor;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
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.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;

public abstract class J2EEArtifactExportDataModelProvider extends AbstractDataModelProvider implements IJ2EEComponentExportDataModelProperties {

    private static final class ArchiveExportParticipantData implements IArchiveExportParticipantData
    {
        private String id = null;
        private IArchiveExportParticipant extension = null;
        private IDataModel datamodel = null;

        public String getId()
        {
            return this.id;
        }
        
        public IArchiveExportParticipant getParticipant()
        {
            return this.extension;
        }
        
        public IDataModel getDataModel()
        {
            return this.datamodel;
        }
    }

    public HashMap componentMap;

	public J2EEArtifactExportDataModelProvider() {
		super();
	}

	@Override
	public Set getPropertyNames() {
		Set propertyNames = super.getPropertyNames();
		propertyNames.add(PROJECT_NAME);
		propertyNames.add(ARCHIVE_DESTINATION);
		propertyNames.add(EXPORT_SOURCE_FILES);
		propertyNames.add(OVERWRITE_EXISTING);
		propertyNames.add(RUN_BUILD);
		propertyNames.add(COMPONENT);
		propertyNames.add(OPTIMIZE_FOR_SPECIFIC_RUNTIME);
		propertyNames.add(RUNTIME);
		propertyNames.add(RUNTIME_SPECIFIC_PARTICIPANTS);
		return propertyNames;
	}

	protected abstract String getProjectType();

	protected abstract String getWrongComponentTypeString(String projectName);

	protected abstract String getModuleExtension();

	@Override
	public Object getDefaultProperty(String propertyName) {
		if (propertyName.equals(ARCHIVE_DESTINATION)) {
			return ""; //$NON-NLS-1$
		} else if (propertyName.equals(EXPORT_SOURCE_FILES)) {
			return Boolean.FALSE;
		} else if (propertyName.equals(OVERWRITE_EXISTING)) {
			return Boolean.FALSE;
		} else if (propertyName.equals(RUN_BUILD)) {
			return Boolean.TRUE;
		} else if (propertyName.equals(RUNTIME_SPECIFIC_PARTICIPANTS)) {
		    return new ArrayList<IArchiveExportParticipantData>();
		} else if(propertyName.equals(OPTIMIZE_FOR_SPECIFIC_RUNTIME)){
			return Boolean.FALSE;
		}
		return super.getDefaultProperty(propertyName);
	}
	
	@Override
	public boolean isPropertyEnabled( final String propertyName )
	{
	    if( propertyName.equals( OPTIMIZE_FOR_SPECIFIC_RUNTIME ) )
	    {
	        return getDataModel().getValidPropertyDescriptors( RUNTIME ).length > 0;
	    }
	    else if( propertyName.equals( RUNTIME ) )
	    {
	        return getBooleanProperty(OPTIMIZE_FOR_SPECIFIC_RUNTIME); 
	    }
	    
	    return true;
	}
	
	@Override
	public boolean propertySet(String propertyName, Object propertyValue) 
	{
		boolean set = super.propertySet(propertyName, propertyValue);
		final IDataModel dm = getDataModel();
		
		if (propertyName.equals(PROJECT_NAME)) {
			if (getComponentMap().isEmpty())
				intializeComponentMap();
			IVirtualComponent component = (IVirtualComponent) getComponentMap().get(propertyValue);
			if (null != component && component.getName().equals(propertyValue)) {
				setProperty(COMPONENT, component);
			} else {
				setProperty(COMPONENT, null);
			}

            dm.notifyPropertyChange( RUNTIME, IDataModel.VALID_VALUES_CHG );
            
            IFacetedProject fproj = null;
            
            if( component != null )
            {
                try
                {
                    fproj = ProjectFacetsManager.create( component.getProject() );
                }
                catch( CoreException e )
                {
                    J2EEPlugin.logError( -1, e.getMessage(), e );
                }
            }
            
            boolean optimize = false;
            IRuntime runtime = null;
            
            if( fproj !=  null )
            {
                runtime = fproj.getPrimaryRuntime();
                
                if( runtime != null )
                {
                    optimize = true;
                }
                else
                {
                    final DataModelPropertyDescriptor[] validValues 
                        = dm.getValidPropertyDescriptors( RUNTIME );
                    
                    if( validValues.length > 0 )
                    {
                        runtime = (IRuntime) validValues[ 0 ].getPropertyValue();
                    }
                }
            }

            setProperty( OPTIMIZE_FOR_SPECIFIC_RUNTIME, optimize);
            setProperty( RUNTIME, runtime );
		}
		else if( propertyName.equals( OPTIMIZE_FOR_SPECIFIC_RUNTIME ) )
		{
            dm.notifyPropertyChange( RUNTIME, IDataModel.ENABLE_CHG );
		}
		else if( propertyName.equals( RUNTIME ) )
		{
            final List<IArchiveExportParticipantData> currentExtDataList
                = (List<IArchiveExportParticipantData>) getProperty( RUNTIME_SPECIFIC_PARTICIPANTS );
            
            if( currentExtDataList != null )
            {
                for( IArchiveExportParticipantData extData : currentExtDataList )
                {
                    dm.removeNestedModel( extData.getId() );
                }
            }
            
            final List<IArchiveExportParticipantData> extensions = new ArrayList<IArchiveExportParticipantData>();
		    
		    if( propertyValue != null )
		    {
		        final IProject project = getProject();
		        
		        if( project != null)
		        {
		            final IRuntime runtime = (IRuntime) propertyValue;
		            
		            for( ArchiveExportParticipantsExtensionPoint.ParticipantInfo partInfo 
		                 : ArchiveExportParticipantsExtensionPoint.getExtensions( project, runtime ) )
		            {
                        ArchiveExportParticipantData partData = new ArchiveExportParticipantData();
                        partData.id = partInfo.getId();
                        partData.extension = partInfo.loadParticipant();
		                
		                if( partData.extension != null )
		                {
		                    try
		                    {
		                        partData.datamodel = partData.extension.createDataModel( dm );
		                        dm.addNestedModel( partData.id, partData.datamodel );
		                    }
		                    catch( Exception e )
		                    {
		                        J2EEPlugin.logError( -1, e.getMessage(), e );
		                        partData = null;
		                    }
		                }
		                else
		                {
		                    partData = null;
		                }
		                
		                if( partData != null )
		                {
		                    extensions.add( partData );
		                }
		            }
		        }
		    }
		    
		    setProperty( RUNTIME_SPECIFIC_PARTICIPANTS, Collections.unmodifiableList( extensions ) );
		}
		
		return set;
	}

	public HashMap getComponentMap() {
		if (componentMap == null)
			componentMap = new HashMap();
		return componentMap;
	}

	public void intializeComponentMap() {
		IVirtualComponent[] comps = ComponentUtilities.getAllWorkbenchComponents();
		for (int i = 0; i < comps.length; i++) {
			getComponentMap().put(comps[i].getName(), comps[i]);
		}
	}

	/**
	 * Populate the resource name combo with projects that are not encrypted.
	 */
	@Override
	public DataModelPropertyDescriptor[] getValidPropertyDescriptors(String propertyName) {
		// TODO: populate valid components
		if (propertyName.equals(PROJECT_NAME)) {
			List componentNames = new ArrayList();
			IVirtualComponent[] wbComps = ComponentUtilities.getAllWorkbenchComponents();

			List relevantComponents = new ArrayList();
			for (int i = 0; i < wbComps.length; i++) {
				if (J2EEProjectUtilities.getJ2EEProjectType(wbComps[i].getProject()).equals(getProjectType())) {
					relevantComponents.add(wbComps[i]);
					getComponentMap().put(wbComps[i].getName(), wbComps[i]);
				}
			}

			if (relevantComponents.size() == 0)
				return null;

			for (int j = 0; j < relevantComponents.size(); j++) {
				componentNames.add(((IVirtualComponent) relevantComponents.get(j)).getName());
			}
			String[] names = (String[]) componentNames.toArray(new String[componentNames.size()]);

			return DataModelPropertyDescriptor.createDescriptors(names);
		}
		else if( propertyName.equals( RUNTIME ) )
		{
            final List<IRuntime> runtimes = new ArrayList<IRuntime>();
		    final IVirtualComponent component = (IVirtualComponent) getProperty( COMPONENT );
		    
	        if( component != null )
            {
                try
                {
                    final IFacetedProject fproj = ProjectFacetsManager.create( component.getProject() );
                    
                    for( IRuntime runtime : RuntimeManager.getRuntimes() )
                    {
                        if( fproj.isTargetable( runtime ) )
                        {
                            runtimes.add( runtime );
                        }
                    }
                    
                    final Comparator<IRuntime> comparator = new Comparator<IRuntime>()
                    {
                        public int compare( final IRuntime r1,
                                            final IRuntime r2 )
                        {
                            return r1.getName().compareTo( r2.getName() );
                        }
                    };
                    
                    Collections.sort( runtimes, comparator );
                }
                catch( CoreException e )
                {
                    J2EEPlugin.logError( -1, e.getMessage(), e );
                }
            }
		    
		    return DataModelPropertyDescriptor.createDescriptors( runtimes.toArray() );		    
		}
		
		return super.getValidPropertyDescriptors(propertyName);
		// (ProjectUtilities.getProjectNamesWithoutForwardSlash((String[])
		// projectsWithNature.toArray(new String[projectsWithNature.size()])));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModel#doValidateProperty(java.lang.String)
	 */
	@Override
	public IStatus validate(String propertyName) {
		if (PROJECT_NAME.equals(propertyName)) {
			String projectName = (String) model.getProperty(PROJECT_NAME);
			if (projectName == null || projectName.equals("")) //$NON-NLS-1$
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.MODULE_EXISTS_ERROR));
			IVirtualComponent component = (IVirtualComponent) componentMap.get(projectName);
			if (component == null) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.MODULE_EXISTS_ERROR));
			}
			if (!J2EEProjectUtilities.getJ2EEProjectType(component.getProject()).equals(getProjectType())) {
				return WTPCommonPlugin.createErrorStatus(getWrongComponentTypeString(projectName));
			}
		}
		if (ARCHIVE_DESTINATION.equals(propertyName)) {
			String archiveLocation = (String) model.getProperty(ARCHIVE_DESTINATION);
			if (!model.isPropertySet(ARCHIVE_DESTINATION) || archiveLocation.equals("")) { //$NON-NLS-1$
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.DESTINATION_INVALID)); //);
			} else if (model.isPropertySet(ARCHIVE_DESTINATION) && !validateModuleType(archiveLocation)) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.DESTINATION_ARCHIVE_SHOULD_END_WITH, new Object[]{getModuleExtension()})); //);
			} else if (model.isPropertySet(ARCHIVE_DESTINATION)) {
				IStatus tempStatus = validateLocation(archiveLocation);
				if (tempStatus != OK_STATUS)
					return tempStatus;
			}
		}
		if (ARCHIVE_DESTINATION.equals(propertyName) || OVERWRITE_EXISTING.equals(propertyName)) {
			String location = (String) getProperty(ARCHIVE_DESTINATION);
			if (checkForExistingFileResource(location)) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.RESOURCE_EXISTS_ERROR, new Object[]{location}));
			}
		}
		return OK_STATUS;
	}

	private IStatus validateLocation(String archiveLocation) {
		IPath path = null;
		try {
			path = new Path(archiveLocation);
		} catch (IllegalArgumentException ex) {
			return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.DESTINATION_INVALID));
		}
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IStatus status = workspace.validateName(path.lastSegment(), IResource.FILE);
		if (!status.isOK()) {
			return status;
		}
		String device = path.getDevice();
		if (device == null)
			return OK_STATUS;
		if (device.length() == 1 && device.charAt(0) == IPath.DEVICE_SEPARATOR)
			return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.DESTINATION_INVALID));

		if (!path.toFile().canWrite()) {
			if (path.toFile().exists()) {
				return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.IS_READ_ONLY));
			}
			boolean OK = false;
			path = path.removeLastSegments(1);
			for (int i = 1; !OK && i < 20 && path.segmentCount() > 0; i++) {
				if (path.toFile().exists()) {
					OK = true;
				}
				status = workspace.validateName(path.lastSegment(), IResource.FOLDER);
				if (!status.isOK()) {
					return WTPCommonPlugin.createErrorStatus(WTPCommonPlugin.getResourceString(WTPCommonMessages.DESTINATION_INVALID));
				}
				path = path.removeLastSegments(1);
			}
		}

		return OK_STATUS;
	}

	private boolean checkForExistingFileResource(String fileName) {
		if (!model.getBooleanProperty(OVERWRITE_EXISTING)) {
			java.io.File externalFile = new java.io.File(fileName);
			if (externalFile.exists())
				return true;
		}
		return false;
	}

	private boolean validateModuleType(String archive) {
		if ((archive.length() < 4) || (!(archive.substring(archive.length() - 4, archive.length()).equalsIgnoreCase(getModuleExtension())))) {
			return false;
		}
		return true;
	}
	
	private IProject getProject()
	{
	    final IVirtualComponent component = (IVirtualComponent) getProperty( COMPONENT );
	    
	    if( component != null )
	    {
	        return component.getProject();
	    }
	    return null;
	}

}
