/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation. 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: Actuate Corporation - initial API and implementation
 ******************************************************************************/

package org.eclipse.birt.test.performance.reporting;

import java.io.Writer;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.birt.test.performance.Constants;
import org.eclipse.birt.test.performance.parser.CaseLogger;
import org.eclipse.birt.test.performance.parser.TestCaseNode;
import org.eclipse.birt.test.performance.parser.CaseLogger.DurationEntry;
import org.eclipse.birt.test.performance.parser.CaseLogger.TaskEntry;
import org.eclipse.birt.test.performance.parser.CaseLogger.ThreadEntry;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Reporter
{

	Writer writer = null;

	public Reporter( Writer writer )
	{
		this.writer = writer;
	}

	public void report( List testcases ) throws ParserConfigurationException
	{
		DomWriter domwriter = new DomWriter( );
		domwriter.setOutput( writer );
		domwriter.setCanonical( true );

		// reporting.
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance( );
		DocumentBuilder builder = builderFactory.newDocumentBuilder( );
		Document doc = builder.newDocument( );

		Element reporting = doc.createElement( "reporting" );
		reporting.setAttribute( "generationDate", Constants.DATE_FORMAT
				.format( Calendar.getInstance( Locale.ENGLISH ).getTime( ) ) );
		doc.appendChild( reporting );

		for ( int i = 0; i < testcases.size( ); i++ )
		{
			TestCaseNode testcase = (TestCaseNode) testcases.get( i );

			Element testcaseElement = doc.createElement( "testcase" );
			reporting.appendChild( testcaseElement );

			testcaseElement.setAttribute( "name", testcase.getName( ) );
			testcaseElement.setAttribute( "thread", String.valueOf( testcase
					.getThreads( ) ) );
			testcaseElement.setAttribute( "locale", testcase.getLocale( ) );
			testcaseElement.setAttribute( "format", testcase.getFormat( ) );

			reporting.appendChild( testcaseElement );

			CaseLogger logger = testcase.getCaseLogger( );

			Iterator taskIter = logger.taskList( ).iterator( );
			while ( taskIter.hasNext( ) )
			{
				String taskName = (String) taskIter.next( );
				Element taskElement = doc.createElement( "task" );
				taskElement.setAttribute( "name", taskName );
				testcaseElement.appendChild( taskElement );

				TaskEntry taskEntry = logger.taskEntry( taskName );
				Iterator sortedThreadIter = taskEntry.sortedThreadList( )
						.iterator( );
				while ( sortedThreadIter.hasNext( ) )
				{
					ThreadEntry threadEntry = (ThreadEntry) sortedThreadIter
							.next( );

					Element threadElement = doc.createElement( "thread" );
					threadElement.setAttribute( "id", String
							.valueOf( threadEntry.getId( ) ) );
					taskElement.appendChild( threadElement );

					Iterator durationIter = threadEntry.sortedDurationList( )
							.iterator( );
					while ( durationIter.hasNext( ) )
					{
						DurationEntry durationEntry = (DurationEntry) durationIter
								.next( );

						Element durationElement = doc
								.createElement( "duration" );
						durationElement.setAttribute( "reportid", durationEntry.getReportId( ) );
						durationElement.setAttribute( "timespan", String
								.valueOf( durationEntry.getTimespan( ) ) );
						durationElement.setAttribute( "report", String
								.valueOf( durationEntry.getReportName( ) ) );

						threadElement.appendChild( durationElement );
					}
				}

				Element avgElement = doc.createElement( "average" );
				taskElement.appendChild( avgElement );

				Iterator avgIter = taskEntry.avgDurations( ).iterator( );
				while ( avgIter.hasNext( ) )
				{

					DurationEntry durationEntry = (DurationEntry) avgIter
							.next( );

					Element durationElement = doc.createElement( "duration" );
					durationElement.setAttribute( "reportid", String
							.valueOf( durationEntry.getReportId( ) ) );
					durationElement.setAttribute( "timespan", String
							.valueOf( durationEntry.getTimespan( ) ) );
					durationElement.setAttribute( "report", String
							.valueOf( durationEntry.getReportName( ) ) );

					avgElement.appendChild( durationElement );
				}
			}
		}

		domwriter.write( doc );

	}
}
