/*******************************************************************************
 * 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>();
		} else if(propertyName.equals(OPTIMIZE_FOR_SPECIFIC_RUNTIME)){
			return Boolean.FALSE;
		}
		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 getBooleanProperty(OPTIMIZE_FOR_SPECIFIC_RUNTIME); 
	    }
	    
	    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;
	    }
	}

}
