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

	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();

	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>();
		}
		return super.getDefaultProperty(propertyName);
	}
	
	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 ( (Boolean) getProperty( OPTIMIZE_FOR_SPECIFIC_RUNTIME ) ).booleanValue();
	    }
	    
	    return true;
	}
	
	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 && propertyValue != 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.
	 */
	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 == null || 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 )
		    {
                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)
	 */
	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 (path == null || 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 != null && 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();
	    }
	    else
	    {
	        return null;
	    }
	}

}
