/*******************************************************************************
 * Copyright (c) 2005 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.wst.command.internal.env.ant;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.command.internal.env.EnvironmentMessages;
import org.eclipse.wst.command.internal.env.core.CommandManager;
import org.eclipse.wst.command.internal.env.core.context.ResourceContext;
import org.eclipse.wst.command.internal.env.core.data.BeanModifier;
import org.eclipse.wst.command.internal.env.core.data.ClassEntry;
import org.eclipse.wst.command.internal.env.core.data.Transformer;
import org.eclipse.wst.command.internal.env.core.fragment.CommandFragment;
import org.eclipse.wst.command.internal.env.eclipse.EclipseEnvironment;
import org.eclipse.wst.command.internal.env.plugin.EnvPlugin;
import org.eclipse.wst.common.environment.ILog;
import org.eclipse.wst.common.environment.IStatusHandler;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;

/**
 * 
 * Access to status handler, log, resource context and command manager.  
 * Initializes data for commands from Ant property files based on antDataMapping extensions. 
 * 
 * @author joan
 *
 */

public class AntEnvironment extends EclipseEnvironment{
	
	private Hashtable antProperties_;
	private Hashtable operationDataRecord_ = new Hashtable();
	private boolean mappingComplete_;
	private ClassEntry classEntry;	
		
	// extensionPoint names and namespace
	private static String MAPPER_EXT_PT = "antDataMapping";  //$NON-NLS-1$
	private static String SCENARIO_EXT_PT = "antScenario";  //$NON-NLS-1$
	private static String EXT_PT_NAMESPACE = "org.eclipse.wst.command.env"; ////$NON-NLS-1$
	
	// antDataMapping extension point attributes
	private static final String MAPPER_OPERATION_ATTRIBUTE= "operation"; //$NON-NLS-1$
	private static final String MAPPER_KEY_ATTRIBUTE= "key"; //$NON-NLS-1$
	private static final String MAPPER_PROPERTY_ATTRIBUTE= "property"; //$NON-NLS-1$
	private static final String MAPPER_TRANSFORM_ATTRIBUTE= "transform"; //$NON-NLS-1$
	private static final String MAPPER_REQUIRED_ATTRIBUTE= "required"; //$NON-NLS-1$
		
	// antScenario extension point attributes
	private static final String SCENARIO_TYPE_ATTRIBUTE = "scenarioType"; //$NON-NLS-1$
	private static final String SCENARIO_CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$

	// Ant property IDs
	private static final String VERBOSE_PROPERTY = "Verbose"; //$NON-NLS-1$
	private static final String SCENARIO_TYPE_PROPERTY = "ScenarioType"; //$NON-NLS-1$
	
    private AntController controller_;
	
	public AntEnvironment(AntController controller, ResourceContext context, IStatusHandler handler, Hashtable properties)
	{
	   super(controller.getOperationManager(), context, handler);
	   antProperties_ = properties;	
	   controller_ = controller;	   
	}
	
	public boolean verbose()
	{
	  String verbose=getProperty(VERBOSE_PROPERTY);		
	  
	  if (verbose != null)
	  {
		  verbose = verbose.toLowerCase();
		  if (verbose.equals("true"))
			  return true;
	  }		  
	  return false;
	}
	
	// returns String since the property table built by Ant is property value pairs where the value is a String
	private String getProperty(String key)
	{
		Object property = antProperties_.get(key);
		if (property != null && (!property.toString().equals("")))
			return property.toString().trim();
		return null;
	}
	
	// call from engine prior to executing the operation 
	public IStatus initOperationData(AbstractDataModelOperation op)
	{
		//check to see if data has already been primed for this operation 
		String qualifiedClassName = op.getClass().getName();
		if (operationDataRecord_.get(qualifiedClassName) == null)
		{
			classEntry = new ClassEntry();
			
			try {
				//extension lookup for the bean - may be more than one property for it
				Enumeration operationData = getMappingExtensions(op);					
				classEntry.setterList_= getSetterList(op);		
				while (operationData.hasMoreElements())
				{				
					PropertyDataHolder mapping = (PropertyDataHolder)operationData.nextElement();
						
					    mappingComplete_ = false;
						String property = mapping.property_;
						String setterMethodName = createSetterName(property);		
												
						int step = 1;
						while (!mappingComplete_)
						{							
						   switch (step) {
							case 1:
								mappingComplete_ = transformAndSet(mapping, setterMethodName);								
								break;								
							case 2:
								mappingComplete_ = callSetter(mapping.operation_, mapping.value_, setterMethodName);
								break;
								
							case 3:
								mappingComplete_ = callPrimitiveSetter(mapping);
								break;
							
							case 4:
								mappingComplete_ = callSetterConstructor(mapping);
								break;
								
							default:
								mappingComplete_ = true;
								break;								
							}
						   step++;
						}					
				  }				
                //add operation to the record - no need to initialize again...
                operationDataRecord_.put(qualifiedClassName, "");
			}			
			catch (Exception e)
			{					                                
				throw new IllegalArgumentException(e.getMessage());
			}

		}
		return Status.OK_STATUS;
	}

	/**
	 * Creates setter name based on the property passed in.  If the 
	 * property has any leading qualifiers they are stripped off.
	 * The property is capitalized and set is prepended.
	 * @param property  The name of the property that requires a setter.
	 * @return
	 */	
	private String createSetterName(String property)
	{		
		while (property.indexOf(".")>=0)
		{
			property=property.substring(property.indexOf(".")+1);
		}		 
		 String firstChar = property.substring(0,1);
		 firstChar = firstChar.toUpperCase();
		 property = firstChar + property.substring(1);  
		 String setterName = "set" + property;		 
		 return setterName;		 
	}	
	
	   /**
	    * Retrieves extensions for the org.eclipse.wst.command.env antDataMapping
	    * extension point.  Extracts those that with class attribute values that match operationName.
	    * All mappings are converted to PropertyDataHolder objects.
	    * Any m:1 Ant key to property mappings are collected into a key-value map within
	    * a single PropertyDataHolder.  
	    * @param operationName The name of the operation that is being initialized.
	    * @return A collection of PropertyDataHolder objects. Returns null if there are no extensions matching the operationName.
	    */
	   private Enumeration getMappingExtensions(AbstractDataModelOperation operation) throws CoreException
	   {	   		   
		   String operationName = operation.getClass().getName();
		   //go to ext registry and get all antMapping extensions
		   IExtensionRegistry reg = Platform.getExtensionRegistry();
		   IExtensionPoint extPt = reg.getExtensionPoint(EXT_PT_NAMESPACE, MAPPER_EXT_PT);
		   Hashtable dataTable = new Hashtable(25);
		   
		   IConfigurationElement[] elements = extPt.getConfigurationElements();
		   
		   for (int i = 0; i < elements.length; i++) {
			
			 IConfigurationElement ce = elements[i];
			 Object obj = ce.getAttribute(MAPPER_OPERATION_ATTRIBUTE);
			 // look for mappings for this operation
			 if (obj.equals(operationName))
			 {				 
				 String key = ce.getAttribute(MAPPER_KEY_ATTRIBUTE);
				 String value = getProperty(key);
				 
				 //check to see if the property for this extension is already in the data table
				 // if so, there is a m:1 mapping
				 if (value != null)  //only do a mapping if there is an Ant property value passed in...
				 {
				
					 String property = ce.getAttribute(MAPPER_PROPERTY_ATTRIBUTE);
					 Object transform = null;
					 try
					 {
						 transform = ce.createExecutableExtension(MAPPER_TRANSFORM_ATTRIBUTE);	 
					 }
					 catch (CoreException cex) {
					   Status errorStatus = new Status(Status.ERROR, "ws_ant", 5092, cex.getMessage(), cex);
					   getStatusHandler().reportError(errorStatus);
					   getLog().log(ILog.ERROR, "ws_ant", 5092, this, "getMappingExtensions", EnvironmentMessages.bind(EnvironmentMessages.MSG_ERROR_ANT_DATA_TRANSFORM, key, transform));
					   throw new CoreException(errorStatus);
					 }
					 
					 if (transform != null && transform instanceof BeanModifier/*dataTable.containsKey(property)*/)
					 {
						 //get the PropertyDataHolder from the table
						 PropertyDataHolder holder = (PropertyDataHolder)dataTable.get(property);
						 if (holder == null)
						 {
							 holder = new PropertyDataHolder();
							 holder.key_ = "";
							 holder.value_ = "";	
							 holder.transform_ = transform;
							 holder.operation_ = operation;
							 holder.property_ = property;
							 holder.map_ = new HashMap();
							 holder.map_.put(key, value);
							 dataTable.put(property, holder);
						 }						 
						 else
						 {						
							holder.map_.put(key, value);
						 }					
					 }
					 else  //plain property mapping not a bean
					 {
						 PropertyDataHolder holder = new PropertyDataHolder();
						 holder.operation_ = operation;
						 holder.key_ = key;
						 holder.property_ = property;
						 holder.transform_ = transform;
						 holder.value_ = value;
						 dataTable.put(property, holder);
					 }			 
				 }
				 else if(ce.getAttribute(MAPPER_REQUIRED_ATTRIBUTE)!=null && ce.getAttribute(MAPPER_REQUIRED_ATTRIBUTE).equals("true"))
				 {				
					 String msg = EnvironmentMessages.bind(EnvironmentMessages.MSG_ERROR_ANT_REQUIRED_PROPERTY, key.toString());
					 Status statusObj = new Status(IStatus.ERROR, 
								EnvPlugin.ID,
								IStatus.ERROR,
								msg, 
								null);
					 getStatusHandler().reportError(statusObj);
	                 getLog().log(ILog.ERROR, "ws_ant", 9999, this, "getMappingExtensions", msg);					 
				 }
				 else if (verbose())
				 {
					 String msg = EnvironmentMessages.bind(EnvironmentMessages.MSG_INFO_ANT__PROPERTY_DEFAULT, key.toString());
					 Status statusObj = new Status(IStatus.INFO, 
								EnvPlugin.ID,
								IStatus.INFO,
								msg, 
								null);
					 getStatusHandler().reportInfo(statusObj);
					 getLog().log(ILog.INFO, "ws_ant", 9999, this, "getMappingExtensions", msg);					 
				 }
		      }    	 
		  }
		   return dataTable.elements();
		}     
	   
	   private boolean transformAndSet(PropertyDataHolder mapping, String setterMethodName)
	   {
			Object transform = mapping.transform_;
			if (transform != null)
			{
				// get transform class & create setter parameters		
				try
				{
					//Object classObject = Class.forName(transform).newInstance();
					Object param = new Object();
					if (transform instanceof Transformer)
					{
						Transformer transformer = (Transformer)transform;						
						// transform the property value
						param = transformer.transform(mapping.value_);						
					}
					else if (mapping.map_ != null && transform instanceof BeanModifier)
					{
						  BeanModifier modifier = (BeanModifier)transform;		
                          Method getter = getGetterMethod(mapping);
						  param = getter.invoke(mapping.operation_, new Object[]{});						  
						  modifier.modify(param, mapping.map_);
					}												
					return callSetter(mapping.operation_, param, setterMethodName);
					
				}
				catch (Exception exc)
				{
					getStatusHandler().reportError(new Status(Status.ERROR, "ws_ant", 5093, exc.getMessage(), exc));
                    getLog().log(ILog.ERROR, "ws_ant", 5093, this, "transformAndSet", EnvironmentMessages.bind(EnvironmentMessages.MSG_ERROR_ANT_DATA_TRANSFORM, mapping.key_, mapping.transform_));
                    throw new IllegalArgumentException(exc.getMessage());
				}				
			}
			return false;
	   }	   
	   
	   private Vector getSetterList(Object op)
	   {
		   Vector result = new Vector();
           Method[] methods = op.getClass().getMethods();		     
		     for( int index = 0; index < methods.length; index++ )
		     {
		       Method  method     = methods[index];
		       boolean isPublic   = Modifier.isPublic( method.getModifiers() );
		       Class   returnType = method.getReturnType();
		     
		       if( isPublic && 
		           returnType == Void.TYPE && 
		           method.getParameterTypes().length == 1 &&
		           method.getName().startsWith( "set" ))
		       {
		         method.setAccessible( true );
		         result.add( method );
		       }
		     }
			     
	     return result;
	   }
	   
	   private Method getGetterMethod(PropertyDataHolder mapping)
	   {
	       Method getterFound = null;     

	       if (classEntry.getterList_ == null)
	       {
	    	   classEntry.getterList_ = getGetterList(mapping.operation_);  
	       }
	       
	       for( int index = 0; index < classEntry.getterList_.size(); index++ )
	       {
	         Method getter = (Method)classEntry.getterList_.elementAt( index );
	         
	         if( getter.getName().equals( "get" + mapping.property_ ))
	         {
	            getterFound = getter;
	            break;
	         }       
	       }
	       return getterFound;
	   }
	   
	   private Vector getGetterList( Object object )
	   {
	     Vector result = new Vector();	     
	     Method[] methods = object.getClass().getMethods();
	     
	     for( int index = 0; index < methods.length; index++ )
	     {
	       Method  method     = methods[index];
	       boolean isPublic   = Modifier.isPublic( method.getModifiers() );
	       Class   returnType = method.getReturnType();
	     
	       if( isPublic && 
	           returnType != Void.TYPE && 
	           method.getParameterTypes().length == 0 &&
	           method.getName().startsWith( "get" ))
	       {
	         method.setAccessible( true );
	         result.add( method );
	       }
	     }
	     
	     return result;
	   }   
       
	   private boolean callSetter(AbstractDataModelOperation op, Object param, String setterMethodName) throws CoreException
	   {
		   for (Iterator iterator = classEntry.setterList_.iterator(); iterator.hasNext();) 
		   {
				Method method = (Method) iterator.next();
				if (method.getName().equals(setterMethodName))
				{                                        
			       Class[] paramTypes = method.getParameterTypes();
			       if (paramTypes.length == 1 && param != null)
			       {			  
			        	 try{			      			
			     			 method.invoke(op, new Object[]{param});
			     			 return true;
			     		 }
			     		 catch(Exception cex){
			     			Status errorStatus = new Status(Status.ERROR, "ws_ant", 5094, cex.getMessage(), cex);
			     			getStatusHandler().reportError(errorStatus);
			     			getLog().log(ILog.ERROR, "ws_ant", 5094, this, "callSetter", EnvironmentMessages.bind(EnvironmentMessages.MSG_ERROR_ANT_CALL_SETTER, setterMethodName));
			     			throw new CoreException(errorStatus);
			     		 }
			       }  
				}
			}
		    return false;
	   }
	   
	
	   // look for setter with primitive type parameter - if find one, convert String propertyValue and call it
	   private boolean callPrimitiveSetter(PropertyDataHolder mapping) throws CoreException
	   {			
			for (Iterator iterator = classEntry.setterList_.iterator(); iterator.hasNext();) {
				Method element = (Method) iterator.next();
				Class[] parmTypes = element.getParameterTypes();
				if (parmTypes.length==1 && parmTypes[0].isPrimitive())
				{										
					Class parmType = parmTypes[0].getClass();
					Object setterParm = null;
					if (parmType.equals(Integer.class))
					{
						setterParm = Integer.valueOf(mapping.value_);
					}
					else if (parmType.equals(Boolean.class))
					{
						setterParm = Boolean.valueOf(mapping.value_);
					}
					else if (parmType.equals(Character.class) && mapping.value_.length() == 1)
					{
						setterParm = new Character(mapping.value_.charAt(0));  
					}
					else if (parmType.equals(Byte.class))
					{
						setterParm = Byte.valueOf(mapping.value_);
					}
					else if (parmType.equals(Short.class))
					{
						setterParm = Short.valueOf(mapping.value_);
					}
					else if (parmType.equals(Long.class))
					{
						setterParm = Long.valueOf(mapping.value_);
					}
					else if (parmType.equals(Float.class))
					{
						setterParm = Float.valueOf(mapping.value_);
					}
					else if (parmType.equals(Double.class))
					{
						setterParm = Double.valueOf(mapping.value_);
					}
														
				    if (setterParm != null)
				    {	
				    	try
				    	{
				    		element.invoke(mapping.operation_, new Object[]{setterParm});
					    	return true;	
				    	}
				    	catch(Exception e){
				    		Status errorStatus = new Status(Status.ERROR, "ws_ant", 5095, e.getMessage(), e);
				    		getStatusHandler().reportError(errorStatus);
				    		getLog().log(ILog.ERROR, "ws_ant", 5095, this, "callPrimitiveSetter", EnvironmentMessages.bind(EnvironmentMessages.MSG_ERROR_ANT_CALL_SETTER, element.getName()));
				    		throw new CoreException(errorStatus);
				    	}
				    }			
				}
		    }   
			return false;
	   }
		
		//check for setter with parameter type that takes a String to construct
		// construct the parameter using String & call the setter  
	   private boolean callSetterConstructor(PropertyDataHolder mapping) throws CoreException
	   {	
			for (Iterator iterator = classEntry.setterList_.iterator(); iterator.hasNext();) {
				Method element = (Method) iterator.next();
				Class[] parmTypes = element.getParameterTypes();
				Class[] stringParm = new Class[]{String.class};
				if (parmTypes.length==1)
				{
					try
					{			
						Constructor ctor = parmTypes.getClass().getConstructor(stringParm);
						Object parameter = ctor.newInstance(new Object[]{mapping.value_});
						element.invoke(mapping.operation_, new Object[]{parameter});						
					}
					catch (Exception exc)
					{
						Status errorStatus = new Status(Status.ERROR, "ws_ant", 5096, exc.getMessage(), exc);
						getStatusHandler().reportError(errorStatus);
						getLog().log(ILog.ERROR, "ws_ant", 5096, this, "callSetterConstructor", EnvironmentMessages.bind(EnvironmentMessages.MSG_ERROR_ANT_CALL_SETTER, element.getName()));
						throw new CoreException(errorStatus);
					}
				}
	        }			
		   return false;
	   }

	   /**
	    * Returns an object that helps manage execution/undoing of Commands.
	    */
	   public CommandManager getCommandManager (){
		   return controller_.getOperationManager();
	   } 
	   
	   public CommandFragment getRootCommandFragment() 
       {
    	   
    	   //look up the commandFragment in the scenarioRegistry extension point with an ID corresponding to the scenario property in the propertytable
    	   String scenarioProperty = (String)getProperty(SCENARIO_TYPE_PROPERTY);
    	   IExtensionRegistry reg = Platform.getExtensionRegistry();
		   IExtensionPoint extPt = reg.getExtensionPoint(EXT_PT_NAMESPACE, SCENARIO_EXT_PT);
		   
		   IConfigurationElement[] elements = extPt.getConfigurationElements();
		   
		   for (int i = 0; i < elements.length; i++) {
			
			 IConfigurationElement configElement = elements[i];			 
			 if (configElement.getAttribute(SCENARIO_TYPE_ATTRIBUTE).equals(scenarioProperty))
			 {				 
				 try
				 {					 
					Object obj = configElement.createExecutableExtension(SCENARIO_CLASS_ATTRIBUTE);
		
					if (obj instanceof org.eclipse.wst.command.internal.env.core.fragment.CommandFragment)
					{
						return (org.eclipse.wst.command.internal.env.core.fragment.CommandFragment)obj;
					}
				 }
				 catch (Exception exception)
				 {
					 Status errorStatus = new Status(Status.ERROR, "ws_ant", 5097, exception.getMessage(), exception);
					 getStatusHandler().reportError(errorStatus);
					 getLog().log(ILog.ERROR, "ws_ant", 5097, this, "getRootCommandFragment", EnvironmentMessages.MSG_ERROR_ANT_CMD_FRAGMENT);					 
				 }				 
			  }    	   
           }
		   return null;
       }
  }
