/*
 * Created on Apr 19, 2005
 *
 */
package com.mastek.calypso.webtest;

import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

import com.canoo.ant.filter.ITableFilter;
import com.canoo.ant.table.APropertyTable;
import com.canoo.ant.table.ExcelPropertyTable;
import com.canoo.ant.table.IPropertyTable;
import com.canoo.ant.table.TableFactory;
import com.canoo.webtest.engine.StepExecutionException;
import com.canoo.webtest.steps.control.MultipleExecutionStepContainer;

/**
 * @author Vikram Shitole
 * 
 */
public class ImportDataStep extends MultipleExecutionStepContainer
{

	private static final Logger	LOG					= Logger.getLogger(ImportDataStep.class);

	public static final String		DEFAULT_STEPTYPE	= "ImportData";

	private String						strFilterClass;

	private String						strTableName;

	private String						strAttributeName;

	private String						strTableClassName;

	private String						strForeignTableName;

	private String						strForeignAttributeName;

	private String						strAttributeValue;

	private String						container;

	private Properties				fProps				= new Properties();

	private List						propertiesList;

	/**
	 * @return Returns the strAttributeName.
	 */
	public String getAttributeName()
	{
		return strAttributeName;
	}

	/**
	 * @param strAttributeName
	 *           The strAttributeName to set.
	 */
	public void setName(String strAttributeName)
	{
		this.strAttributeName = strAttributeName;
	}

	/**
	 * @return Returns the strAttributeValue.
	 */
	public String getAttributeValue()
	{
		return strAttributeValue;
	}

	/**
	 * @param strAttributeValue
	 *           The strAttributeValue to set.
	 */
	public void setValue(String strAttributeValue)
	{
		this.strAttributeValue = strAttributeValue;
	}

	/**
	 * @return Returns the strFilterClass.
	 */
	public String getFilterClass()
	{
		return strFilterClass;
	}

	/**
	 * @param strFilterClass
	 *           The strFilterClass to set.
	 */
	public void setFilterClass(String strFilterClass)
	{
		this.strFilterClass = strFilterClass;
		fProps.setProperty(TableFactory.KEY_FILTER_CLASS, strFilterClass);
	}

	/**
	 * @return Returns the strForeignAttributeName.
	 */
	public String getForeignAttributeName()
	{
		return strForeignAttributeName;
	}

	/**
	 * @param strForeignAttributeName
	 *           The strForeignAttributeName to set.
	 */
	public void setForeignName(String strForeignAttributeName)
	{
		this.strForeignAttributeName = strForeignAttributeName;
	}

	/**
	 * @return Returns the strForeignTableName.
	 */
	public String getForeignTableName()
	{
		return strForeignTableName;
	}

	/**
	 * @param strForeignTableName
	 *           The strForeignTableName to set.
	 */
	public void setForeignTable(String strForeignTableName)
	{
		this.strForeignTableName = strForeignTableName;
	}

	/**
	 * @return Returns the strTableClassName.
	 */
	public String getTableClassName()
	{
		return strTableClassName;
	}

	/**
	 * @param strTableClassName
	 *           The strTableClassName to set.
	 */
	public void setTableclass(String strTableClassName)
	{
		this.strTableClassName = strTableClassName;
		fProps.setProperty(TableFactory.KEY_TABLE_CLASS, strTableClassName);
	}

	/**
	 * @return Returns the strTableName.
	 */
	public String getTableName()
	{
		return strTableName;
	}

	/**
	 * @param strTableName
	 *           The strTableName to set.
	 */
	public void setTable(String strTableName)
	{
		this.strTableName = strTableName;
		fProps.setProperty(TableFactory.KEY_FOREIGN_TABLE, strTableName);
	}

	/**
	 * @return Returns the fProps.
	 */
	public Properties getFProps()
	{
		return fProps;
	}

	public void doExecute() throws CloneNotSupportedException
	{
		setTaskType(DEFAULT_STEPTYPE);
		verifyParameters();

		IPropertyTable table;
		ITableFilter filter;
		try
		{
			table = TableFactory.createTable(getFProps(), ExcelPropertyTable.class.getName());
			filter = TableFactory.createFilter(getFProps());
		}
		catch (Exception e)
		{
			throw new BuildException("cannot create container", e, getLocation());
		}

		TableFactory.initOrDefault(table, filter, getFProps(), null, getAttributeName());

		propertiesList = table.getPropertiesList(getAttributeValue(), null);

		LOG.debug("propertiesList.size() = " + propertiesList.size());
		if (propertiesList.size() < 1)
		{
			LOG.warn("no match found in" + " table " + table.getClass().getName() + " with filter " + table.getFilter().getClass().getName() + " and settings " + getFProps().toString() + " raw data:" + ((APropertyTable) table).getRawTable());
		}

		for (int i = 0; i < propertiesList.size(); i++)
		{
			setDataAsProperties((Properties) propertiesList.get(i));
			final Task iterationWrapper = createIterationWrapper("ImportData Iteration " + i);
			iterationWrapper.perform();
		}
	}

	protected void verifyParameters()
	{
		super.verifyParameters();
		if (getContainerTable() == null || getContainerTable().equals(""))
			throw new StepExecutionException("Please specify the excel file path.", this);
		if (getTableName() == null || getTableName().equals(""))
			throw new StepExecutionException("Please specify the excel worsksheet name.", this);
		if (getFilterClass() == null || getFilterClass().equals(""))
			throw new StepExecutionException("Please specify the filter class.", this);

	}

	private void setDataAsProperties(Properties propSet)
	{
		for (Iterator eachKey = propSet.keySet().iterator(); eachKey.hasNext();)
		{
			String key = (String) eachKey.next();
			String value = propSet.getProperty(key);
			LOG.debug("setting key/value" + key + "/" + value);
			setWebtestProperty(key, value);
		}
	}

	public void setContainer(String container)
	{
		this.container = container;
		fProps.setProperty(TableFactory.KEY_CONTAINER, this.container);
	}

	public String getContainerTable()
	{
		return container;
	}

}