package org.eclipse.wst.web.internal.facet;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentType;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentVersion;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.eclipse.wst.web.internal.WSTWebPlugin;

public class RuntimePresetMappingRegistry {

	static final String EXTENSION_POINT = "runtimePresetMappings";

	static final String ELEMENT_MAPPING = "mapping";

	static final String ATTRIBUTE_ID = "id";

	static final String ATTRIBUTE_FACET_RUNTIME_TYPE_ID = "facetRuntimeTypeID";

	static final String ATTRIBUTE_FACET_RUNTIME_VERSION = "facetRuntimeVersion";

	static final String ATTRIBUTE_FACET_ID = "facetID";

	static final String ATTRIBUTE_FACET_VERSION = "facetVersion";

	static final String ATTRIBUTE_PRESET_ID = "presetID";

	public static RuntimePresetMappingRegistry INSTANCE = new RuntimePresetMappingRegistry();

	private List<MappingDescriptor> descriptors = null;

	public String getPresetID(String facetRuntimeTypeID,
			String facetRuntimeVersion, String facetID, String facetVersion) {
		if (descriptors == null) {
			readDescriptors();
		}
		for (MappingDescriptor descriptor : descriptors) {
			if(matches(facetRuntimeTypeID, descriptor.getFacetRuntimeTypeID()) &&
			   matches(facetRuntimeVersion, descriptor.getFacetRuntimeVersion()) &&
			   matches(facetID, descriptor.getFacetID()) &&
			   matches(facetVersion, descriptor.getFacetVersion())){
				return descriptor.getPresetID();
			}
		}
		return null;
	}

	/**
	 * Returns true if the value is matched by the pattern The pattern consists
	 * of a common deliminated list of simple patterns Each simple pattern has
	 * an optional starting or ending * so a String.startsWith() or
	 * String.endsWith(). Both may be combined to compute a String.indexOf() !=
	 * -1
	 *
	 * @param value
	 * @param pattern
	 * @return
	 */
	private static boolean matches(String value, String pattern){
		StringTokenizer strTok = new StringTokenizer(pattern, ",");
		while(strTok.hasMoreTokens()){
			String simplePattern = strTok.nextToken().trim();
			if(simplePattern.startsWith("*")){
				if(simplePattern.length() < 2){
					return true; // i.e. *
				}
				if(simplePattern.endsWith("*")){
					if(simplePattern.length() < 3){ 
						return true; // i.e. **
					}
					if(value.indexOf(simplePattern.substring(1, simplePattern.length()-2)) != -1){
						return true;
					}
				} else {
					if(value.endsWith(simplePattern.substring(1))){
						return true;
					}
				}
			} else if(simplePattern.endsWith("*")){
				if(value.startsWith(simplePattern.substring(0, simplePattern.length()-2))){
					return true;
				}
			} else if(value.equals(simplePattern)){
				return true;
			}
		}
		return false;
	}
	
	private static List <String> getStaticTokens(String pattern){
		List <String> staticTokens = new ArrayList <String> ();
		StringTokenizer strTok = new StringTokenizer(pattern, ",");
		while(strTok.hasMoreTokens()){
			String simplePattern = strTok.nextToken().trim();
			if(!simplePattern.startsWith("*") && !simplePattern.endsWith("*")){
				staticTokens.add(simplePattern);
			}
		}
		return staticTokens;
	}
	
	
	private void readDescriptors() {
		descriptors = new ArrayList<MappingDescriptor>();
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(WSTWebPlugin.PLUGIN_ID, EXTENSION_POINT);
		if (point == null)
			return;
		IConfigurationElement[] elements = point.getConfigurationElements();
		for (int i = 0; i < elements.length; i++) {
			IConfigurationElement element = elements[i];
			if (ELEMENT_MAPPING.equals(element.getName())) {
				String id = element.getAttribute(ATTRIBUTE_ID);
				if (null == id || id.trim().length() == 0) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " is missing attribute " + ATTRIBUTE_ID);
					continue;
				}

				String runtimeID = element.getAttribute(ATTRIBUTE_FACET_RUNTIME_TYPE_ID);
				if (null == runtimeID || runtimeID.trim().length() == 0) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " is missing attribute " + ATTRIBUTE_FACET_RUNTIME_TYPE_ID);
					continue;
				}

				List <String> staticRuntimeIDs = getStaticTokens(runtimeID);
				List <IRuntimeComponentType> staticRuntimeTypes = new ArrayList<IRuntimeComponentType>();
				for(String staticRuntimeID : staticRuntimeIDs){
					try {
						IRuntimeComponentType runtimeType = RuntimeManager.getRuntimeComponentType(staticRuntimeID);
						if(runtimeType != null){
							staticRuntimeTypes.add(runtimeType);
						}
					} catch (IllegalArgumentException e) {
						WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " defined invalid attribute " + ATTRIBUTE_FACET_RUNTIME_TYPE_ID + ": " + runtimeID +" unable to resolve runtime: "+staticRuntimeID, e);
					}
				}
					
				String runtimeVersionStr = element.getAttribute(ATTRIBUTE_FACET_RUNTIME_VERSION);
				if (null == runtimeVersionStr || runtimeVersionStr.trim().length() == 0) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " is missing attribute " + ATTRIBUTE_FACET_RUNTIME_VERSION);
					continue;
				}
				if(!staticRuntimeTypes.isEmpty()){
					List <String> staticRuntimeVersions = getStaticTokens(runtimeVersionStr);
					for(String staticVersion : staticRuntimeVersions){
						boolean foundVersion = false;
						for(int k=0;k<staticRuntimeTypes.size() && !foundVersion;k++){
							IRuntimeComponentType runtimeType = staticRuntimeTypes.get(k);
							try {
								IRuntimeComponentVersion version = runtimeType.getVersion(staticVersion);
								foundVersion = true;
							} catch (IllegalArgumentException e) {
								//eat it
							}
						}
						if(!foundVersion){
							StringBuffer validVersions = new StringBuffer(" valid versions include: ");
							for(IRuntimeComponentType runtimeType : staticRuntimeTypes) {
								validVersions.append("\n");
								validVersions.append(runtimeType.getId());
								validVersions.append(": ");
								for (Iterator<IRuntimeComponentVersion> iterator = runtimeType.getVersions().iterator(); iterator.hasNext();) {
									validVersions.append(iterator.next().getVersionString());
									if (iterator.hasNext()) {
										validVersions.append(" ");
									}
								}
							}
							WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " defined invalid attribute " + ATTRIBUTE_FACET_RUNTIME_VERSION + ": " + staticVersion
									+ validVersions);
						}
					}
				}
				
				String facetID = element.getAttribute(ATTRIBUTE_FACET_ID);
				if (null == facetID || facetID.trim().length() == 0) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " is missing attribute " + ATTRIBUTE_FACET_ID);
					continue;
				}
				
				List <String> staticFacetIDs = getStaticTokens(facetID);
				List <IProjectFacet> staticFacets = new ArrayList <IProjectFacet>();
				for(String staticFacetID:staticFacetIDs){
					try {
						IProjectFacet facet = ProjectFacetsManager.getProjectFacet(staticFacetID);
						if(null != facet){
							staticFacets.add(facet);
						}
					} catch (IllegalArgumentException e) {
						WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " defined invalid attribute " + ATTRIBUTE_FACET_ID + ": " + staticFacetID, e);
					}
				}
				
				String facetVersionStr = element.getAttribute(ATTRIBUTE_FACET_VERSION);
				if (null == facetVersionStr || facetVersionStr.trim().length() == 0) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " is missing attribute " + ATTRIBUTE_FACET_VERSION);
					continue;
				}
				List <String>staticFacetVersionStrs = getStaticTokens(facetVersionStr);
				if(!staticFacets.isEmpty() && !staticFacetVersionStrs.isEmpty()){
					for(String staticFacetVersion:staticFacetVersionStrs){
						boolean foundFacetVersion = false;
						for(int k=0;k< staticFacets.size() && !foundFacetVersion; k++) {
							IProjectFacet staticFacet = staticFacets.get(k);
							try {
								IProjectFacetVersion staticVersion = staticFacet.getVersion(staticFacetVersion);
								if(staticVersion != null){
									foundFacetVersion = true;
								}
							} catch (IllegalArgumentException e) {
								//eat it
							}
						}
						if(!foundFacetVersion){
							StringBuffer validVersions = new StringBuffer(" valid versions include: ");
							for(IProjectFacet staticFacet:staticFacets){
								validVersions.append("\n");
								validVersions.append(staticFacet.getId());
								validVersions.append(": ");
								for (Iterator<IProjectFacetVersion> iterator = staticFacet.getVersions().iterator(); iterator.hasNext();) {
									validVersions.append(iterator.next().getVersionString());
									if (iterator.hasNext()) {
										validVersions.append(" ");
									}
								}
							}
							WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " defined invalid attribute " + ATTRIBUTE_FACET_VERSION + ": " + staticFacetVersion
									+ validVersions);
							continue;
						}
					}	
				}
				String presetID = element.getAttribute(ATTRIBUTE_PRESET_ID);
				if (null == presetID || presetID.trim().length() == 0) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " is missing attribute " + ATTRIBUTE_PRESET_ID);
					continue;
				}
				try {
					ProjectFacetsManager.getPreset(presetID);
				} catch (IllegalArgumentException e) {
					WSTWebPlugin.logError("Extension: " + EXTENSION_POINT + " Element: " + ELEMENT_MAPPING + " defined invalid attribute " + ATTRIBUTE_PRESET_ID + ": " + presetID, e);
					continue;
				}
				MappingDescriptor descriptor = new MappingDescriptor(element);
				descriptors.add(descriptor);
			} else {
				WSTWebPlugin.logError("Elements must be named: " + ELEMENT_MAPPING + " within the extension: " + EXTENSION_POINT);
				WSTWebPlugin.logError("Element: " + element.getName() + " is invalid within the extension: " + EXTENSION_POINT);
			}
		}
	}

}