<?xml version="1.0" encoding="utf-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" 
		 implements="flexunit.flexui.IFlexWriter" creationComplete="onCreationComplete()" xmlns:geom="flash.geom.*" currentState="StackTraceView">
	<mx:Script>
		<![CDATA[
		
		import mx.collections.ArrayCollection;
		
		import flexunit.framework.TestCase;
		import flexunit.framework.Test;
		import flexunit.framework.AssertionFailedError;
		import flexunit.flexui.TestRunner;
		import flexunit.flexui.IFlexWriter;
		
		import mx.collections.ListCollectionView;
		
		import flash.system.*;

		public var beforeTest:Function;
		public var afterTest:Function; 		
		
		public var suiteMetaData:Object;
		
		private static const END_OF_TEST_RUN : String = "<endOfTestRun/>";
		private static const END_OF_TEST_ACK : String ="<endOfTestRunAck/>";
		
		private var _totalTests:uint = 0;
		private var _totalErrors:uint = 0;
		private var _totalFailures:uint = 0;
		private var _numTestsRun:uint = 0;
		
		public var test:Test;
		
		private var reports : Object = new Object();
		private var socket : XMLSocket;
		private var connectionTries : int = 0;
    	private var connectionTryMax : int = 10;
		
		public var reportXML : Boolean = true;
		[Inspectable]
		public var port : uint = 1024;		
		[Inspectable]
		public var server : String = "127.0.0.1";
		
		public function onCreationComplete():void
		{
			suiteMetaData = new Object();
		}
		
		public function startTest():void
		{
		
			flexunit.flexui.TestRunner.afterTest = afterTest;
			flexunit.flexui.TestRunner.beforeTest = beforeTest;			

			if( test != null )
			{				
				_totalTests = test.countTestCases();
				
				progressBar.minimum = 0;
				testFailures.dataProvider = new Array();
				allTestsList.dataProvider = new Array();
				
				updateLabels();
				
				flexunit.flexui.TestRunner.run( test, this );
			}
		}		
		
		private function updateLabels():void
		{
			runLabel.htmlText = "<b>Run:</b> "+_numTestsRun.toString()+"/"+_totalTests.toString();
			errorsLabel.htmlText = "<b>Errors:</b> "+_totalErrors.toString();
			failuresLabel.htmlText = "<b>Failures:</b> "+_totalFailures.toString();
		}
		
		private function updateProgress():void
		{
			progressBar.setProgress( _numTestsRun, _totalTests );
			
			if( _totalErrors > 0 || _totalFailures > 0 )
				progressBar.setStyle("barColor",0xFF0000);
		}
		
		private function addFailureToList( test:Test, error:Error ):void
		{
			var t:TestCase = test as TestCase;
			if( t != null )
			{
				ListCollectionView(testFailures.dataProvider).addItem( {label: t.toString(), error:error} );
				testFailures.selectedIndex = testFailures.dataProvider.length;
				testFailures.verticalScrollPosition = testFailures.maxVerticalScrollPosition;
				onTestSelected();
			}
		}
		
		private function onTestSelected():void
		{
			var list:List = (testTabs.selectedIndex == 0) ? testFailures : allTestsList;
			var errorString:String;
			
			if( list.selectedItem != null )
				if( list.selectedItem.error != null )
				{
					this.currentState = "StackTraceView";
					errorString = list.selectedItem.error.getStackTrace();
					if (errorString == null)
					{
						errorString = list.selectedItem.error.message;
					}
					stackTrace.text = errorString;
					testDetails.text = "Stack Trace";
				}
				else
				{ 
					this.currentState = "ResultsView";
					//testDetails.text = "Test Details";
					var dp_TestResults:ArrayCollection = new ArrayCollection();
					var dp_MemUsage:ArrayCollection = new ArrayCollection();
					resultsGrid.dataProvider = dp_TestResults;
					rawMemGrid.dataProvider = dp_MemUsage;
					var setUpDuration : String = list.selectedItem.setUpDuration.toFixed(3);
					var middleDuration : String = list.selectedItem.middleDuration.toFixed(3);
					var tearDownDuration : String = list.selectedItem.tearDownDuration.toFixed(3);
					dp_TestResults.addItem({stage: "SetUp", duration: setUpDuration, memUsage: list.selectedItem.setUpMemFinal - list.selectedItem.setUpMemInitial});
					dp_TestResults.addItem({stage: "Middle", duration: middleDuration, memUsage: list.selectedItem.middleMemFinal - list.selectedItem.middleMemInitial});
					dp_TestResults.addItem({stage: "TearDown", duration: tearDownDuration, memUsage: list.selectedItem.tearDownMemFinal - list.selectedItem.tearDownMemInitial});
					dp_MemUsage.addItem({initialMem: list.selectedItem.setUpMemInitial, finalMem: list.selectedItem.tearDownMemFinal, memDifference: (list.selectedItem.tearDownMemFinal - list.selectedItem.setUpMemInitial)});
					dp_TestResults = null;
					dp_MemUsage = null;
				}	
		}
		
		private function addTestToList( success:Boolean, test:Test, error:Error = null ):void
		{
			var t:TestCase = test as TestCase;
			if( t != null )
			{
				var label:String = ( success ) ? "[PASS] " : "[FAIL] ";
				// get mem data from test here - don't add it to the data provider
				ListCollectionView(allTestsList.dataProvider).addItem( {label:label+t.toString(), 
																		error:error, 
																		setUpDuration:t.setUpDuration,
																		middleDuration:t.middleDuration,
																		tearDownDuration:t.tearDownDuration,
																		setUpMemInitial:t.setUpMemInitial,
																		setUpMemFinal:t.setUpMemFinal,
																		middleMemInitial:t.middleMemInitial,
																		middleMemFinal:t.middleMemFinal,
																		tearDownMemInitial:t.tearDownMemInitial,
																		tearDownMemFinal:t.tearDownMemFinal
																		} );
				allTestsList.selectedIndex = allTestsList.dataProvider.length;
				allTestsList.verticalScrollPosition = allTestsList.maxVerticalScrollPosition;
				onTestSelected();
			}			
		}
		
		//---------------------------------------------------------------------
		// IFlexWriter Methods
		//---------------------------------------------------------------------
		
		public function onTestStart( test:Test ) : void
		{
			titlePanel.title = "Test Runner (running: " + test.toString() + ")";
			if (reportXML)
				addMethod( test );
		}
		
		public function onTestEnd( test:Test ) : void
		{
			//only run if reportXML is enabled
			if (reportXML)
			{
				if (test is TestCase)
				{
					var time : Number = TestCase(test).setUpDuration + TestCase(test).middleDuration + TestCase(test).tearDownDuration;
					
					// Add time to the method.
					var methodObject : Object = getMethod( test );
					methodObject.time = time; 
					methodObject.setuptime = TestCase(test).setUpDuration;
					methodObject.setupmeminitial = TestCase(test).setUpMemInitial;
					methodObject.setupmemfinal = TestCase(test).setUpMemFinal;
					methodObject.middletime = TestCase(test).middleDuration;
					methodObject.middlememinitial = TestCase(test).middleMemInitial;
					methodObject.middlememfinal = TestCase(test).middleMemFinal;
					methodObject.teardowntime = TestCase(test).tearDownDuration;
					methodObject.teardownmeminitial = TestCase(test).tearDownMemInitial;
					methodObject.teardownmemfinal = TestCase(test).tearDownMemFinal;
				}
				
				Security.loadPolicyFile("xmlsocket:\\" + server + ":" + port);
				// If we have finished running all the tests send the results.
				if ( (_numTestsRun+1) == _totalTests )
				{
					sendResults();
   				}
   			}
   			_numTestsRun++;			
			updateLabels();
			updateProgress();
			titlePanel.title = "Test Runner";
		}
		
		public function onAllTestsEnd() : void
		{
			progressBar.setProgress(100,100);
			if( _totalErrors == 0 && _totalFailures == 0 )
				progressBar.setStyle("barColor",0x00FF00);
		}
		
		public function onSuccess( test:Test ):void
		{
			addTestToList( true, test );
		}
		
 	   	public function onError( test:Test, error:Error ) : void
 	   	{
 	   		_totalErrors++;
 	   		addFailureToList( test, error );
 	   		addTestToList( false, test, error );
 	   		
			if (reportXML)
 	   			addError( test, error);
 	   	}
 	   	
		public function onFailure( test:Test, error:AssertionFailedError ) : void
		{
			_totalFailures++;
			addFailureToList( test, error );
			addTestToList( false, test, error );

			if (reportXML)
				addFailure( test, AssertionFailedError(error));
		}
		
		//---------------------------------------------------------------------
		// JUnitRunner Methods
		//---------------------------------------------------------------------
		
		/**
		 * Add the currently executing method on a Test to the internal report
		 * model.
		 * @param test the Test.
		 */
		private function addMethod( test : Test ) : void
		{
			var reportObject : Object = getReport( test );
			reportObject.tests++;
			
			var methodName : String = TestCase(test).toString();
			var methodsObject : Object = reportObject.methods;
			
			var methodObject : Object = new Object();
			methodsObject[ methodName ] = methodObject;

			methodObject.classname = test.className;
			methodObject.metaData = TestCase(test).metaData;
			methodObject.name = methodName;
			methodObject.time = 0.0;
			methodObject.setuptime = 0.0;
			methodObject.setupmeminitial = 0.0;
			methodObject.setupmemfinal = 0.0;
			methodObject.middletime = 0.0;
			methodObject.middlememinitial = 0.0;
			methodObject.middlememfinal = 0.0;
			methodObject.teardowntime = 0.0;
			methodObject.teardownmeminitial = 0.0;
			methodObject.teardownmemfinal = 0.0;

		}
		
		/**
		 * Called when an error occurs.
		 * @param test the Test that generated the error.
		 * @param error the Error.
		 */
		public function addError( test : Test, error : Error ) : void
		{
			// Increment error count.
			var report : Object = getReport( test );
			report.errors++;
			
			// Add the error to the method.
			var methodObject : Object = getMethod( test );
			
			var errorObject : Object = new Object();
			methodObject.error = errorObject;

			errorObject.type = getClassName( error );
			errorObject.message = error.message;
		}

		/**
		 * Called when a failure occurs.
		 * @param test the Test that generated the failure.
		 * @param error the failure.
		 */
		public function addFailure( test : Test, error : AssertionFailedError ) : void
		{
			// Increment failure count.
			var report : Object = getReport( test );
			report.failures++;
			
			// Add the failure to the method.
			var methodObject : Object = getMethod( test );
			
			var failureObject : Object = new Object();
			methodObject.failure = failureObject;

			failureObject.type = getClassName( error );
			failureObject.message = error.message;
		}
		
		/**
		 * Return the fully qualified class name for an Object.
		 * @param obj the Object.
		 * @return the class name.
		 */
		private function getClassName( obj : Object ) : String
		{
			var description : XML = describeType( obj );
			var className : Object = description.@name;
			
			return className[ 0 ];
		}
		
		/**
		 * Return the method Object from the internal report model for the
		 * currently executing method on a Test.
		 * @param test the Test.
		 * @return the method Object.
		 */
		private function getMethod( test : Test ) : Object
		{
			var reportObject : Object = getReport( test );
			var methodsObject : Object = reportObject.methods;
			
			var methodName : String = TestCase(test).toString()
			
			return methodsObject[ methodName ];
		}
	
		/**
		 * Return the report Object from the internal report model for the
		 * currently executing Test.
		 * @param Test the test.
		 */
		private function getReport( test : Test ) : Object
		{
			var reportObject : Object;
			var className : String = test.className;
			
			// Check we have a report Object for the executing Test, if not
			// create a new one.
			if ( reports[ className ] )
			{
				reportObject = reports[ className ];
			}
			else
			{
				reportObject = new Object();
				reportObject.name = className;
				reportObject.errors = 0;
				reportObject.failures = 0;
				reportObject.tests = 0;
				reportObject.time = getTimer()/1000;
				reportObject.methods = new Object();
				
				reports[ className ] = reportObject;
			}
			
			return reportObject;
		}
		
		/**
		 * Sends the results. This sends the reports back to the controlling Ant
		 * task using an XMLSocket.
		 */
		public function sendResults() : void
		{
			// Open an XML socket.
			socket = new XMLSocket();
			socket.addEventListener( Event.CONNECT, handleConnect );
			socket.addEventListener( DataEvent.DATA, dataHandler );
			socket.addEventListener( IOErrorEvent.IO_ERROR, handleIOError );
			socket.addEventListener( SecurityErrorEvent.SECURITY_ERROR, handleSecurityError );
			socket.connect( server, port );
		}
		
		private function handleSecurityError( event : Event ) : void
		{
			var e:SecurityErrorEvent = event as SecurityErrorEvent;
			throw new Error("SecurityErrorEvent on Connect-> " + e.target + ": " +
				e.type + ". " + e.text + "."); 
		}

		private function handleIOError( event : Event ) : void
		{
			if(connectionTries <= connectionTryMax){
				connectionTries++;
				sendResults();
			}else{
				var e:IOErrorEvent = event as IOErrorEvent;
				throw new Error("IOErrorEvent on Connect-> " + e.target + ": " +
					e.type + ". " + e.text + ". " + socket.connected + " " + server + ":" + port);				
			}
		}
		
		/**
		 * Event listener to handle data received on the socket.
		 * @param event the DataEvent.
		 */
		private function dataHandler( event : DataEvent ) : void
		{
			var data : String = event.data;

			// If we received an acknowledgement finish-up.			
			if ( data == END_OF_TEST_ACK )
			{
				exit();
			}
   		}
   		
   		private function handleConnect( event : Event ) : void
		{
			for ( var className : String in reports )
			{
				// Create the XML report.
				var xml : XML = createXMLReport( reports[ className ] );
				
				// Send the XML report.
				socket.send( xml.toXMLString() );
			}
			
			// Send the end of reports terminator.
			socket.send( END_OF_TEST_RUN );
		}
		
		/**
		 * Create the XML report.
		 * @param obj the report Object.
		 * @return the XML report.
		 */
		private function createXMLReport( obj : Object ) : XML
		{
			// Create the test suite element.
			var testSuite : XML = createTestSuite( obj );
				
			// Create the test case elements.					
			var methodsObject : Object = obj.methods;
			for ( var methodName : String in methodsObject )
			{
				var methodObject : Object = methodsObject[ methodName ];
				var testCase : XML = createTestCase( methodObject );
						
				// Create the failure element.
				if ( methodObject.failure )
				{
					var failureObject : Object = methodObject.failure;			
					var failure : XML = createFailure( failureObject );
							
					testCase = testCase.appendChild( failure );									
				}
					
				// Create the error element.
				if ( methodObject.error )
				{
					var errorObject : Object = methodObject.error;
					var error : XML = createError( errorObject );
							
					testCase = testCase.appendChild( error );									
				}					
							
				testSuite = testSuite.appendChild( testCase );
			}
			
			return testSuite;
		}
		
		/**
		 * Create the test suite XML.
		 * @return the XML.
		 */ 
		private function createTestSuite( obj : Object ) : XML
		{
			var name : String = obj.name;
			var errors : uint = obj.errors;
			var failures : uint = obj.failures;
			var tests : uint = obj.tests;
			var time : int = getTimer()/1000 - obj.time;
			var methods : Object = obj.methods;
			var flashVersion : String = Capabilities.version;
			var flashLanguage : String = Capabilities.language;
			var flashPlayerType : String = Capabilities.playerType;
			var flashConfig : String;
			
			setDebugFlag();
			if (debugMode)
			{
				flashConfig = "release debugger";
			}
			else
			{
				flashConfig = "release";
			}
				
			var xml : XML =
				<testsuite
					errors={ errors }
					failures={ failures }
					name={ formatQualifiedClassName( name ) }
					tests={ tests }
					time={ time }
					flashversion={ flashVersion }
					flashlanguage={ flashLanguage }
					flashconfig={ flashConfig }
					flashplayertype={ flashPlayerType }/>;
			
			// Add any other meta-data
			for (var attrib:Object in suiteMetaData)
			{
				xml.@[attrib] = suiteMetaData[attrib];	
			}
			
			return xml;
		}
		
		/**
		 * Create the test case XML.
		 * @return the XML.
		 */
		private function createTestCase( obj : Object ) : XML
		{
			var classname : String = obj.classname;
			var name : String = obj.name;
			var time : Number = obj.time; 
			var setuptime : Number = obj.setuptime;
			var setupmeminitial : Number = obj.setupmeminitial;
			var setupmemfinal : Number = obj.setupmemfinal;
			var middletime : Number = obj.middletime;
			var middlememinitial : Number = obj.middlememinitial;
			var middlememfinal : Number = obj.middlememfinal;
			var teardowntime : Number = obj.teardowntime;
			var teardownmeminitial : Number = obj.teardownmeminitial;
			var teardownmemfinal : Number = obj.teardownmemfinal;
					
			var xml : XML =
				<testcase
					classname={ formatQualifiedClassName( classname ) }
					name={ name }
					time={ time.toFixed(3) }
					setuptime={ setuptime.toFixed(3) }
					setupmeminitial={ setupmeminitial }
					setupmemfinal={ setupmemfinal }
					middletime={ middletime.toFixed(3) }
					middlememinitial={ middlememinitial }
					middlememfinal={ middlememfinal }
					teardowntime={ teardowntime.toFixed(3) }
					teardownmeminitial={ teardownmeminitial }
					teardownmemfinal={ teardownmemfinal }/>;
			
			// Add any other meta-data
			for (var attrib:Object in obj.metaData)
			{
				xml.@[attrib] = obj.metaData[attrib];	
			}
			
			return xml;
		}
		
		/**
		 * Create the failure XML.
		 * @return the XML.
		 */
		private function createFailure( obj : Object ) : XML
		{
			var type : String = obj.type;
			var message : String = obj.message;
					
			var xml : XML =
				<failure type={ formatQualifiedClassName( type ) }>
					{ message }
				</failure>;
					
			return xml;
		}
		
		/**
		 * Create the test error XML.
		 * @return the XML.
		 */
		private function createError( obj : Object ) : XML
		{
			var type : String = obj.type;
			var message : String = obj.message;
					
			var xml : XML =
				<error type={ formatQualifiedClassName( type ) }>
					{ message }
				</error>;
					
			return xml;
		}
		
		/**
		 * Exit the test runner and close the player.
		 */
		private function exit() : void
		{
			// Close the socket.
			socket.close();
		}
		
		private function formatQualifiedClassName( className : String ) : String
		{
			var pattern : RegExp = /::/;
			
			return className.replace( pattern, "." );
		}
		
		private function setDebugFlag(): void
		{
			var e:Error = new Error();
			var s:String = e.getStackTrace();
			try
			{
				var i:int = s.indexOf("setDebugFlag");
				if (s.charAt(i + 14) == '[')
					debugMode = true;
			}
			catch (err:Error)	// error is thrown in release player
			{
				debugMode = false;
			}
		}

		private var debugMode : Boolean = false;
		
		]]>
	</mx:Script>
	<mx:states>
		<mx:State name="StackTraceView" basedOn="">
			<mx:AddChild relativeTo="{stackTrace}" position="lastChild" creationPolicy="all" />
		</mx:State>
		<mx:State name="ResultsView" basedOn="">
			<mx:RemoveChild target="{stackTrace}" />
			<mx:AddChild relativeTo="{vbox1}" position="lastChild">
				<mx:DataGrid id="resultsGrid" rowCount="3" width="100%" draggableColumns="false" sortableColumns="false">
					<mx:columns>
						<mx:DataGridColumn headerText="Stage" dataField="stage"/>
						<mx:DataGridColumn headerText="Duration (s)" dataField="duration"/>
						<mx:DataGridColumn headerText="Memory Usage (MB)" dataField="memUsage"/>
					</mx:columns>
				</mx:DataGrid>
			</mx:AddChild>
			<mx:AddChild relativeTo="{vbox1}" position="lastChild">
				<mx:DataGrid id="rawMemGrid" editable="false" width="100%" rowCount="1" draggableColumns="false" sortableColumns="false">
					<mx:columns>
						<mx:DataGridColumn headerText="Initial Memory (MB)" dataField="initialMem"/>
						<mx:DataGridColumn headerText="Final Memory (MB)" dataField="finalMem"/>
						<mx:DataGridColumn headerText="Total Usage (MB)" dataField="memDifference"/>
					</mx:columns>
				</mx:DataGrid>
			</mx:AddChild>
		</mx:State>
	</mx:states>
	<mx:Canvas width="100%" height="100%">
		<mx:Panel id="titlePanel" backgroundAlpha="0.4" title="Test Runner" paddingBottom="10" width="100%" height="100%">
			<mx:HBox width="100%">
				<mx:HBox width="50%" height="20" horizontalAlign="left" paddingLeft="0" paddingRight="10">
					<mx:ProgressBar width="100%" trackHeight="12" id="progressBar" labelPlacement="left" label="Running..." mode="manual" />
				</mx:HBox>
				<mx:HBox width="50%" height="20" horizontalAlign="right">
					<mx:Label id="runLabel" paddingRight="10" />
					<mx:Label id="errorsLabel" text="Errors: 0" paddingRight="10" />
					<mx:Label id="failuresLabel" text="Failures: 0" />					
				</mx:HBox>
			</mx:HBox>
			<mx:HDividedBox width="100%" height="100%">
				<mx:TabNavigator id="testTabs" change="onTestSelected()" width="50%" 
					height="100%" paddingBottom="0" paddingLeft="0" paddingRight="0" 
					paddingTop="0" creationPolicy="all" >
					<mx:Canvas label="Failures" width="100%" height="100%">
						<mx:List id="testFailures" width="100%" height="100%" borderStyle="none" editable="true"
								 change="onTestSelected()" />
					</mx:Canvas>
					<mx:Canvas label="All Tests" width="100%" height="100%">
						<mx:List id="allTestsList" width="100%" height="100%" borderStyle="none"
								 change="onTestSelected()" />								
					</mx:Canvas>
				</mx:TabNavigator>					
				<mx:VBox width="50%" height="100%" id="vbox1">
					<mx:HBox width="100%" height="15" paddingBottom="0" 
								paddingLeft="0" paddingRight="0" paddingTop="0">
						<mx:Label id="testDetails"></mx:Label>
					</mx:HBox>
					<mx:TextArea id="stackTrace" width="100%" height="100%" borderStyle="none" wordWrap="false" />
				</mx:VBox>				
			</mx:HDividedBox>
		</mx:Panel>
	</mx:Canvas>
</mx:VBox>