
package org.eclipse.birt.tests.data.engine.regression;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.birt.core.data.DataType;
import org.eclipse.birt.data.engine.api.IResultIterator;
import org.eclipse.birt.data.engine.api.IScriptExpression;
import org.eclipse.birt.data.engine.api.querydefn.ColumnDefinition;
import org.eclipse.birt.data.engine.api.querydefn.QueryDefinition;
import org.eclipse.birt.data.engine.api.querydefn.ScriptDataSetDesign;
import org.eclipse.birt.data.engine.api.querydefn.ScriptDataSourceDesign;
import org.eclipse.birt.data.engine.api.querydefn.ScriptExpression;

import testutil.APITestCase;

/**
 * <b>Bug description</b>
 * <p>
 * aggregation expression data type automatically convertion even if given it a
 * data type
 * <p>
 * <p>
 * Description:
 * </p>
 * aggregation expression data type automatically convertion
 * <p>
 * steps to reproduce:
 * </p>
 * <ol>
 * <li>Create an aggregation expression with script expression class
 * <li>Define the expression with data type integer
 * </ol>
 * <p>
 * Actual result:
 * </p>
 * the output aggregation expression data type show on as numeric
 * 
 * <p>
 * Expected result:
 * </p>
 * when set aggregation expression with interger data type, expected the data
 * type to be integer,not numeric <b>Test description</b>
 * <p>
 * Create a scripted data and set several Alias with data type on it.
 * <P>
 * To identify the data type got from getResultMetaData is the same as originals
 * <P>
 */

public class Regression_112288 extends APITestCase
{

	// data set name
	private final String dataSetName = "ScriptedDataSet";

	// column name
	private String[] scriptColumnNames = new String[]{"NUM", "SQUARE", "STR",
			"ANY"};

	private int[] scriptColumnTypes = new int[]{DataType.INTEGER_TYPE,
			DataType.DOUBLE_TYPE, DataType.STRING_TYPE, DataType.ANY_TYPE};

	// column alias name
	private String[] scriptColumnAliasNames = new String[]{"NUM2", "SQUARE2",
			"STR2", "ANY2"};

	private IScriptExpression[] scriptExprs;

	// private IScriptExpression[] aliasScriptExprs;

	private ScriptDataSourceDesign dsource;

	private ScriptDataSetDesign dset;

	/*
	 * @see org.eclipse.birt.data.engine.api.APITestCase#getDataSourceInfo()
	 */
	protected DataSourceInfo getDataSourceInfo( )
	{
		return null;
	}

	/**
	 * @param dynamicMetadata
	 * @throws Exception
	 */
	private void init( ) throws Exception
	{
		// Create script data set and data source
		dsource = new ScriptDataSourceDesign( "JUST as place folder" );
		dset = newDataSet( null );
		dset.setDataSource( dsource.getName( ) );

		dataEngine.defineDataSource( dsource );
		dataEngine.defineDataSet( dset );

		// Generate script expressions
		scriptExprs = new IScriptExpression[]{
				new ScriptExpression( "dataSetRow." + scriptColumnNames[0] ),
				new ScriptExpression( "dataSetRow." + scriptColumnNames[1] ),
				new ScriptExpression( "dataSetRow." + scriptColumnNames[2] ),
				new ScriptExpression( "Total.sum(dataSetRow."
						+ scriptColumnNames[3] + ")" )};

	}

	private ScriptDataSetDesign newDataSet( String name )
	{
		ScriptDataSetDesign dataSet = new ScriptDataSetDesign( name == null
				? dataSetName
				: name );

		// 1: add scripts
		dataSet.setOpenScript( "count=10;" );

		dataSet
				.setFetchScript( "if (count==0) {return false; } else "
						+ "{ row.NUM=count; row.SQUARE=count*count; row.STR=\"row#\" + count; "
						+ " row[4]=count<5; " + "--count; return true; }" );

		// 2: add column hints - only in the case of static metadata

		dataSet.getResultSetHints( ).addAll( getColumnHints( ) );

		return dataSet;
	}

	private List getColumnHints( )
	{
		ArrayList list = new ArrayList( );
		for ( int i = 0; i < scriptColumnNames.length; i++ )
		{
			ColumnDefinition col = new ColumnDefinition( scriptColumnNames[i] );
			col.setDataType( scriptColumnTypes[i] );

			list.add( col );
		};
		return list;
	}

	/**
	 * Test fetch with alias
	 * 
	 * @throws Exception
	 */
	public void testGetScriptedDatasetAlias( ) throws Exception
	{
		init( );

		QueryDefinition rqDefn = new QueryDefinition( );

		rqDefn.setDataSetName( dataSetName );
		for ( int i = 0; i < this.scriptExprs.length; i++ )
		{
			rqDefn.addResultSetExpression( "_" + scriptColumnNames[i],
					scriptExprs[i] );
		}

		IResultIterator resultIter = this.executeQuery( rqDefn );

		for ( int i = 1; i < 4; i++ )
		{
			assertEquals( scriptColumnTypes[i - 1], resultIter
					.getResultMetaData( ).getColumnType( i ) );
		}

	}

}