/*
 *  soapUI, copyright (C) 2004-2012 smartbear.com 
 *
 *  soapUI is free software; you can redistribute it and/or modify it under the 
 *  terms of version 2.1 of the GNU Lesser General Public License as published by 
 *  the Free Software Foundation.
 *
 *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
 *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 *  See the GNU Lesser General Public License for more details at gnu.org.
 */

package com.eviware.soapui.security.panels;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Date;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.ListModel;
import javax.swing.SwingConstants;
import javax.swing.text.Document;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
import com.eviware.soapui.impl.wsdl.panels.support.MockSecurityTestRunner;
import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetCredentialsAction;
import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetEndpointAction;
import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
import com.eviware.soapui.impl.wsdl.support.HelpUrls;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.security.SecurityScan;
import com.eviware.soapui.model.testsuite.TestCaseRunContext;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.TestRunner.Status;
import com.eviware.soapui.model.testsuite.TestStepResult;
import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
import com.eviware.soapui.security.SecurityTest;
import com.eviware.soapui.security.SecurityTestRunContext;
import com.eviware.soapui.security.SecurityTestRunner;
import com.eviware.soapui.security.SecurityTestRunnerImpl;
import com.eviware.soapui.security.actions.SecurityTestOptionsAction;
import com.eviware.soapui.security.log.JFunctionalTestRunLog;
import com.eviware.soapui.security.log.JSecurityTestRunLog;
import com.eviware.soapui.security.result.SecurityResult.ResultStatus;
import com.eviware.soapui.security.result.SecurityScanRequestResult;
import com.eviware.soapui.security.result.SecurityScanResult;
import com.eviware.soapui.security.result.SecurityTestStepResult;
import com.eviware.soapui.security.support.ProgressBarSecurityTestAdapter;
import com.eviware.soapui.security.support.SecurityTestRunListenerAdapter;
import com.eviware.soapui.settings.UISettings;
import com.eviware.soapui.support.DateUtil;
import com.eviware.soapui.support.DocumentListenerAdapter;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.SwingActionDelegate;
import com.eviware.soapui.support.components.GroovyEditorComponent;
import com.eviware.soapui.support.components.GroovyEditorInspector;
import com.eviware.soapui.support.components.JComponentInspector;
import com.eviware.soapui.support.components.JFocusableComponentInspector;
import com.eviware.soapui.support.components.JInspectorPanel;
import com.eviware.soapui.support.components.JInspectorPanelFactory;
import com.eviware.soapui.support.components.JUndoableTextArea;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.soapui.support.dnd.JListDragAndDropable;
import com.eviware.soapui.support.swing.ComponentBag;
import com.eviware.soapui.support.types.StringToObjectMap;
import com.eviware.soapui.ui.support.KeySensitiveModelItemDesktopPanel;

/**
 * SecurityTest desktop panel
 * 
 * 
 * this is just first rough version created by copy-pasting from
 * WsdlTestCaseDesktoppanel therefore a lot of variables have not been renamed
 * yet, and a lot of code my be unused, or missing
 * 
 * @author dragica.soldo
 */

@SuppressWarnings( "serial" )
public class SecurityTestDesktopPanel extends KeySensitiveModelItemDesktopPanel<SecurityTest>
{
	private JSecurityTestTestStepList testStepList;
	private JProgressBar progressBar;
	private JButton runButton;
	private JButton cancelButton;
	private SecurityTestRunner runner;
	private JButton setEndpointButton;
	private JButton setCredentialsButton;
	private JButton optionsButton;
	private JSecurityTestRunLog securityTestLog;
	private JFunctionalTestRunLog functionalTestLog;
	// private JToggleButton loopButton;
	private ProgressBarSecurityTestAdapter progressBarAdapter;
	private ComponentBag stateDependantComponents = new ComponentBag();
	private boolean canceled;
	private JTextArea descriptionArea;
	private PropertyHolderTable propertiesTable;
	private GroovyEditorComponent tearDownGroovyEditor;
	private GroovyEditorComponent setupGroovyEditor;
	private JInspectorPanel testStepListInspectorPanel;
	private JInspectorPanel inspectorPanel;
	private SecurityTestRunner lastRunner;
	private SecurityTest securityTest;
	private JXToolBar toolbar;
	private InternalSecurityTestRunListener securityTestRunListener = new InternalSecurityTestRunListener();
	private JLabel cntLabel;
	private JComponentInspector<?> securityLogInspector;
	private JComponentInspector<?> functionalLogInspector;
	private ResultStatus securityStatus;
	private ResultStatus functionalStatus;
	private boolean startStepLogEntryAdded;

	public SecurityTestDesktopPanel( SecurityTest securityTest )
	{
		super( securityTest );

		buildUI();

		setPreferredSize( new Dimension( 400, 550 ) );
		this.securityTest = securityTest;
		securityTest.addSecurityTestRunListener( securityTestRunListener );
		progressBarAdapter = new ProgressBarSecurityTestAdapter( progressBar, securityTest, cntLabel );
	}

	protected JSecurityTestTestStepList getTestStepList()
	{
		return testStepList;
	}

	protected JSecurityTestRunLog getSecurityTestLog()
	{
		return securityTestLog;
	}

	protected void setTestStepList( JSecurityTestTestStepList testStepList )
	{
		this.testStepList = testStepList;
	}

	private void buildUI()
	{
		JPanel panel = new JPanel( new BorderLayout() );

		panel.add( buildToolbar(), BorderLayout.PAGE_START );
		panel.add( buildRunnerBar(), BorderLayout.CENTER );

		add( panel, BorderLayout.NORTH );

		JComponent securityLog = buildSecurityLog();
		inspectorPanel = JInspectorPanelFactory.build( buildContent() );
		securityLogInspector = new JComponentInspector<JComponent>( securityLog, "Security Log",
				"Security Execution Log", true );
		inspectorPanel.addInspector( securityLogInspector );
		JComponent functionalLog = buildFunctionalLog();
		functionalLogInspector = new JComponentInspector<JComponent>( functionalLog, "TestCase Log",
				"Functional Execution Log", true );
		inspectorPanel.addInspector( functionalLogInspector );
		inspectorPanel.setDefaultDividerLocation( 0.7F );
		inspectorPanel.setCurrentInspector( "Security Log" );

		if( StringUtils.hasContent( getModelItem().getDescription() )
				&& getModelItem().getSettings().getBoolean( UISettings.SHOW_DESCRIPTIONS ) )
		{
			testStepListInspectorPanel.setCurrentInspector( "Description" );
		}
		initializeStatusIcons();

		add( inspectorPanel.getComponent(), BorderLayout.CENTER );
	}

	private void initializeStatusIcons()
	{
		securityStatus = ResultStatus.UNKNOWN;
		updateStatusIcon( securityStatus, securityLogInspector );

		functionalStatus = ResultStatus.UNKNOWN;
		updateStatusIcon( functionalStatus, functionalLogInspector );
	}

	private void updateStatusIcon( ResultStatus status, JComponentInspector<?> logInspector )
	{
		switch( status )
		{
		case FAILED :
		{
			logInspector.setIcon( UISupport.createImageIcon( "/failed_securitytest.gif" ) );
			// inspectorPanel.activate( logInspector );
			break;
		}
		case UNKNOWN :
		{
			logInspector.setIcon( UISupport.createImageIcon( "/unknown_securitytest.gif" ) );
			break;
		}
		case OK :
		{
			logInspector.setIcon( UISupport.createImageIcon( "/valid_securitytest.gif" ) );
			// inspectorPanel.deactivate();
			break;
		}
		}
	}

	private Component buildRunnerBar()
	{
		progressBar = new JProgressBar( 0, getModelItem().getSecurityScanCount() );

		JPanel progressPanel = new JPanel( new BorderLayout( 10, 0 ) );

		progressBar.setValue( 0 );
		progressBar.setStringPainted( true );
		progressBar.setString( "" );
		progressBar.setIndeterminate( false );

		progressBar.setBorder( BorderFactory.createMatteBorder( 0, 0, 1, 1, Color.LIGHT_GRAY ) );

		progressPanel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
		progressPanel.add( progressBar );

		progressBar.setMinimumSize( new Dimension( 0, 200 ) );
		progressBar.setBackground( Color.WHITE );

		cntLabel = new JLabel( "" );
		cntLabel.setForeground( Color.white );
		cntLabel.setPreferredSize( new Dimension( 50, 18 ) );
		cntLabel.setHorizontalTextPosition( SwingConstants.CENTER );
		cntLabel.setHorizontalAlignment( SwingConstants.CENTER );
		cntLabel.setBorder( BorderFactory.createLineBorder( Color.LIGHT_GRAY ) );

		progressPanel.add( cntLabel, BorderLayout.EAST );

		return progressPanel;
	}

	private JComponent buildSecurityLog()
	{
		securityTestLog = new JSecurityTestRunLog( getModelItem() );
		stateDependantComponents.add( securityTestLog );
		return securityTestLog;
	}

	private JComponent buildFunctionalLog()
	{
		functionalTestLog = new JFunctionalTestRunLog( getModelItem() );
		stateDependantComponents.add( functionalTestLog );
		return functionalTestLog;
	}

	private JComponent buildContent()
	{
		JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
		testStepListInspectorPanel = JInspectorPanelFactory.build( buildTestStepList(), SwingConstants.BOTTOM );

		tabs.addTab( "TestSteps", testStepListInspectorPanel.getComponent() );

		addTabs( tabs, testStepListInspectorPanel );
		tabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );

		return UISupport.createTabPanel( tabs, true );
	}

	protected JComponent buildTestStepList()
	{
		testStepList = new JSecurityTestTestStepList( getModelItem(), securityTestLog );
		return testStepList;
	}

	protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
	{
		inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(), descriptionArea,
				"Description", "SecurityTest Description", true ) );
		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildPropertiesPanel(), "Properties",
				"SecurityTest level properties", true ) );
		inspectorPanel.addInspector( new GroovyEditorInspector( buildSetupScriptPanel(), "Setup Script",
				"Script to run before tunning a SecurityTest" ) );
		inspectorPanel.addInspector( new GroovyEditorInspector( buildTearDownScriptPanel(), "TearDown Script",
				"Script to run after a SecurityTest Run" ) );
	}

	protected GroovyEditorComponent buildTearDownScriptPanel()
	{
		tearDownGroovyEditor = new GroovyEditorComponent( new TearDownScriptGroovyEditorModel(), null );
		return tearDownGroovyEditor;
	}

	protected GroovyEditorComponent buildSetupScriptPanel()
	{
		setupGroovyEditor = new GroovyEditorComponent( new SetupScriptGroovyEditorModel(), null );
		return setupGroovyEditor;
	}

	protected JComponent buildPropertiesPanel()
	{
		JPanel panel = new JPanel( new BorderLayout() );
		propertiesTable = buildPropertiesTable();
		panel.add( propertiesTable, BorderLayout.CENTER );
		return panel;
	}

	protected PropertyHolderTable buildPropertiesTable()
	{
		return new PropertyHolderTable( getModelItem() );
	}

	private JPanel buildDescriptionPanel()
	{
		JPanel panel = new JPanel( new BorderLayout() );
		descriptionArea = new JUndoableTextArea( getModelItem().getDescription() );
		descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
		{
			public void update( Document document )
			{
				getModelItem().setDescription( descriptionArea.getText() );
			}
		} );

		panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
		panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
		UISupport.addTitledBorder( panel, "SecurityTest Description" );

		return panel;
	}

	protected Component buildToolbar()
	{
		toolbar = UISupport.createToolbar();

		runButton = UISupport.createToolbarButton( new RunSecurityTestAction() );
		optionsButton = UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
				SecurityTestOptionsAction.SOAPUI_ACTION_ID, getModelItem(), null, "/options.gif" ) );
		optionsButton.setText( null );
		cancelButton = UISupport.createToolbarButton( new CancelRunSecuritytestAction(), false );

		// loopButton = new JToggleButton( UISupport.createImageIcon( "/loop.gif"
		// ) );
		// loopButton.setPreferredSize( UISupport.getPreferredButtonSize() );
		// loopButton.setToolTipText( "Loop TestCase continuously" );

		setCredentialsButton = UISupport.createToolbarButton( new SetCredentialsAction( getModelItem().getTestCase() ) );
		setEndpointButton = UISupport.createToolbarButton( new SetEndpointAction( getModelItem().getTestCase() ) );

		stateDependantComponents.add( runButton );
		stateDependantComponents.add( optionsButton );
		stateDependantComponents.add( cancelButton );
		stateDependantComponents.add( setCredentialsButton );
		stateDependantComponents.add( setEndpointButton );

		addToolbarActions( toolbar );

		toolbar.addSeparator();
		toolbar.add( Box.createHorizontalGlue() );
		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.SECURITYTESTEDITOR_HELP_URL ) ) );

		return toolbar;
	}
	
	protected JButton getSetEndpointButton()
	{
		return setEndpointButton;
	}

	public JButton getOptionsButton()
	{
		return optionsButton;
	}

	public void setOptionsButton( JButton optionsButton )
	{
		this.optionsButton = optionsButton;
	}

	protected void addToolbarActions( JToolBar toolbar )
	{
		toolbar.add( runButton );
		toolbar.add( cancelButton );
		// toolbar.add( loopButton );
		toolbar.addSeparator();
		toolbar.add( setCredentialsButton );
		toolbar.add( setEndpointButton );
		toolbar.addSeparator();
		toolbar.add( optionsButton );

	}

	protected void runSecurityTest()
	{
		initializeStatusIcons();
		if( canceled )
		{

			// make sure state is correct
			runButton.setEnabled( true );
			cancelButton.setEnabled( false );
			return;
		}

		runButton.setEnabled( false );
		cancelButton.setEnabled( true );
		StringToObjectMap properties = new StringToObjectMap();
		// properties.put( "loopButton", loopButton );
		properties.put( TestCaseRunContext.INTERACTIVE, Boolean.TRUE );
		lastRunner = null;

		runner = getModelItem().run( properties, true );
	}

	public class RunSecurityTestAction extends AbstractAction
	{
		public RunSecurityTestAction()
		{
			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
			putValue( Action.SHORT_DESCRIPTION, "Runs this securitytest" );
		}

		public void actionPerformed( ActionEvent e )
		{
			canceled = false;
			// shouldRun is indicator is there any security scan that can be run
			// meaning security scan have at least one scan and it is not disabled.
			boolean shouldRun = false;
			for( List<SecurityScan> scanList : securityTest.getSecurityScansMap().values() )
				for( SecurityScan scan : scanList )
					if( !scan.isDisabled() )
						shouldRun = true;
			if( shouldRun )
				runSecurityTest();
			else
				UISupport.showInfoMessage( "No Security Scans available to run.", "Security Test Warning" );
		}
	}

	public class CancelRunSecuritytestAction extends AbstractAction
	{
		public CancelRunSecuritytestAction()
		{
			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
			putValue( Action.SHORT_DESCRIPTION, "Stops running this securitytest" );
		}

		public void actionPerformed( ActionEvent e )
		{
			if( runner != null )
				runner.cancel( "canceled in UI" );

			canceled = true;
		}
	}

	@Override
	protected boolean release()
	{
		testStepList.release();
		setupGroovyEditor.release();
		tearDownGroovyEditor.release();
		functionalTestLog.release();
		return super.release();
	}

	public boolean onClose( boolean canCancel )
	{
		if( canCancel )
		{
			if( runner != null && runner.getStatus() == TestCaseRunner.Status.RUNNING )
			{
				Boolean retval = UISupport.confirmOrCancel( "Cancel running SecurityTest?", "Cancel Run" );

				if( retval == null )
					return false;
				if( retval.booleanValue() )
				{
					if( runner != null )
						runner.cancel( null );
				}
			}
		}
		else
		{
			if( runner != null && runner.getStatus() == TestCaseRunner.Status.RUNNING )
			{
				if( runner != null )
					runner.cancel( null );
			}
		}

		getModelItem().removeSecurityTestRunListener( securityTestRunListener );
		progressBarAdapter.release();
		propertiesTable.release();
		inspectorPanel.release();

		setupGroovyEditor.getEditor().release();
		tearDownGroovyEditor.getEditor().release();

		securityTestLog.release();
		lastRunner = null;

		return release();
	}

	protected void beforeRun()
	{
	}

	protected void afterRun()
	{
		runButton.setEnabled( true );
		cancelButton.setEnabled( false );
		testStepList.setEnabled( true );
	}

	private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
	{
		@Override
		public Action createRunAction()
		{
			return new AbstractAction()
			{

				public void actionPerformed( ActionEvent e )
				{

					MockSecurityTestRunner securityTestRunner = new MockSecurityTestRunner( SecurityTestDesktopPanel.this
							.getModelItem() );
					try
					{
						SecurityTestDesktopPanel.this.getModelItem().runStartupScript(
								( SecurityTestRunContext )securityTestRunner.getRunContext(), securityTestRunner );
					}
					catch( Exception e1 )
					{
						UISupport.showErrorMessage( e1 );
					}

				}
			};
		}

		public SetupScriptGroovyEditorModel()
		{
			super( new String[] { "log", "testCase", "context", "testRunner" }, SecurityTestDesktopPanel.this
					.getModelItem(), "Setup" );
		}

		public String getScript()
		{
			return SecurityTestDesktopPanel.this.getModelItem().getStartupScript();
		}

		public void setScript( String text )
		{
			SecurityTestDesktopPanel.this.getModelItem().setStartupScript( text );
		}
	}

	private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
	{
		@Override
		public Action createRunAction()
		{
			return new AbstractAction()
			{

				public void actionPerformed( ActionEvent e )
				{
					try
					{
						MockSecurityTestRunner securityTestRunner = new MockSecurityTestRunner( SecurityTestDesktopPanel.this
								.getModelItem() );
						SecurityTestDesktopPanel.this.getModelItem().runTearDownScript(
								( SecurityTestRunContext )securityTestRunner.getRunContext(), securityTestRunner );
					}
					catch( Exception e1 )
					{
						UISupport.showErrorMessage( e1 );
					}
				}
			};
		}

		public TearDownScriptGroovyEditorModel()
		{
			super( new String[] { "log", "securityTest", "context", "testRunner" }, SecurityTestDesktopPanel.this
					.getModelItem(), "TearDown" );
		}

		public String getScript()
		{
			return SecurityTestDesktopPanel.this.getModelItem().getTearDownScript();
		}

		public void setScript( String text )
		{
			SecurityTestDesktopPanel.this.getModelItem().setTearDownScript( text );
		}
	}

	public static class ModelItemListDragAndDropable extends JListDragAndDropable<JList>
	{
		public ModelItemListDragAndDropable( JList list, WsdlTestCase testCase )
		{
			super( list, testCase );
		}

		@Override
		public ModelItem getModelItemAtRow( int row )
		{
			return ( ModelItem )getList().getModel().getElementAt( row );
		}

		@Override
		public int getModelItemRow( ModelItem modelItem )
		{
			ListModel model = getList().getModel();

			for( int c = 0; c < model.getSize(); c++ )
			{
				if( model.getElementAt( c ) == modelItem )
					return c;
			}

			return -1;
		}

		public Component getRenderer( ModelItem modelItem )
		{
			return getList().getCellRenderer().getListCellRendererComponent( getList(), modelItem,
					getModelItemRow( modelItem ), true, true );
		}

		@Override
		public void setDragInfo( String dropInfo )
		{
			super.setDragInfo( dropInfo == null || dropInfo.length() == 0 ? null : dropInfo );
		}
	}

	public SecurityTestRunner getSecurityTestRunner()
	{
		return runner == null ? lastRunner : runner;
	}

	public boolean dependsOn( ModelItem modelItem )
	{
		SecurityTest securityTest = getModelItem();

		return modelItem == securityTest || modelItem == securityTest.getTestCase()
				|| modelItem == securityTest.getTestCase().getTestSuite()
				|| modelItem == securityTest.getTestCase().getTestSuite().getProject();
	}

	protected SecurityTest getSecurityTest()
	{
		return securityTest;
	}

	public class InternalSecurityTestRunListener extends SecurityTestRunListenerAdapter
	{

		public InternalSecurityTestRunListener()
		{
		}

		public void beforeRun( TestCaseRunner testRunner, SecurityTestRunContext runContext )
		{
			securityTestLog.clear();
			functionalTestLog.clear();

			runButton.setEnabled( false );
			cancelButton.setEnabled( true );
			testStepList.setEnabled( false );
			// testStepList.setSelectedIndex( -1 );
			String start = DateUtil.formatExtraFull( new Date() );
			securityTestLog.addText( "SecurityTest started at " + start );
			functionalTestLog.addText( "Test started at " + start );

			SecurityTestDesktopPanel.this.beforeRun();

			progressBar.setValue( 0 );
			progressBar.setString( "" );

			if( runner == null )
				runner = ( SecurityTestRunnerImpl )testRunner;

			securityStatus = ResultStatus.UNKNOWN;
		}

		public void afterRun( TestCaseRunner testRunner, SecurityTestRunContext runContext )
		{
			SecurityTestRunnerImpl securityRunner = ( SecurityTestRunnerImpl )testRunner;

			if( testRunner.getStatus() == SecurityTestRunner.Status.CANCELED )
			{
				securityTestLog.addText( "SecurityTest canceled [" + testRunner.getReason() + "], time taken = "
						+ securityRunner.getTimeTaken() );
				functionalTestLog.addText( "FunctionalTest canceled [" + testRunner.getReason() + "], time taken = "
						+ securityRunner.getFunctionalTimeTaken() );
			}
			else if( testRunner.getStatus() == SecurityTestRunner.Status.FAILED )
			{
				String msg = securityRunner.getReason();
				if( securityRunner.getError() != null )
				{
					if( msg != null )
						msg += ":";

					msg += securityRunner.getError();
				}

				securityTestLog
						.addText( "SecurityTest failed [" + msg + "], time taken = " + securityRunner.getTimeTaken() );
				if( functionalStatus == ResultStatus.OK )
				{
					functionalTestLog.addText( "FunctionalTest finished with status [" + functionalStatus
							+ "], time taken = " + securityRunner.getFunctionalTimeTaken() );
				}
				else if( functionalStatus == ResultStatus.FAILED )
				{
					functionalTestLog.addText( "FunctionalTest failed [Failing due to failed test step], time taken = "
							+ securityRunner.getFunctionalTimeTaken() );
				}
			}
			else
			{
				securityTestLog.addText( "SecurityTest finished with status [" + testRunner.getStatus()
						+ "], time taken = " + securityRunner.getTimeTaken() );
				if( functionalStatus == ResultStatus.OK )
				{
					functionalTestLog.addText( "FunctionalTest finished with status [" + functionalStatus
							+ "], time taken = " + securityRunner.getFunctionalTimeTaken() );
				}
				else if( functionalStatus == ResultStatus.FAILED )
				{
					functionalTestLog.addText( "FunctionalTest failed [Failing due to failed test step], time taken = "
							+ securityRunner.getFunctionalTimeTaken() );
				}
			}

			lastRunner = runner;
			runner = null;

			// JToggleButton loopButton = ( JToggleButton )runContext.getProperty(
			// "loopButton" );
			// if( loopButton != null && loopButton.isSelected()
			// && testRunner.getStatus() == SecurityTestRunner.Status.FINISHED )
			// {
			// SwingUtilities.invokeLater( new Runnable()
			// {
			// public void run()
			// {
			// runSecurityTest();
			// }
			// } );
			// }
			// else
			// {
			SecurityTestDesktopPanel.this.afterRun();
			// }

			if( testRunner.getStatus() == Status.FAILED )
			{
				securityStatus = ResultStatus.FAILED;
			}
			else if( testRunner.getStatus() == Status.FINISHED || testRunner.getStatus() == Status.CANCELED )
			{
				if( securityStatus != ResultStatus.FAILED )
					securityStatus = ResultStatus.OK;
			}
			updateStatusIcon( securityStatus, securityLogInspector );
			updateStatusIcon( functionalStatus, functionalLogInspector );
		}

		@Override
		public void beforeSecurityScan( TestCaseRunner testRunner, SecurityTestRunContext runContext,
				SecurityScan securityCheck )
		{
			securityTestLog.addSecurityScanResult( securityCheck );
		}

		@Override
		public void afterSecurityScan( TestCaseRunner testRunner, SecurityTestRunContext runContext,
				SecurityScanResult securityCheckResult )
		{
			securityTestLog.updateSecurityScanResult( securityCheckResult );

			if( securityCheckResult.getStatus() == ResultStatus.CANCELED
					&& securityCheckResult.isHasRequestsWithWarnings() )
			{
				securityStatus = ResultStatus.FAILED;
			}
			else if( securityCheckResult.getStatus() == ResultStatus.FAILED )
			{
				securityStatus = ResultStatus.FAILED;
			}
			else if( securityCheckResult.getStatus() == ResultStatus.OK )
			{
				if( securityStatus != ResultStatus.FAILED )
					securityStatus = ResultStatus.OK;
			}

		}

		@Override
		public void afterOriginalStep( TestCaseRunner testRunner, SecurityTestRunContext runContext,
				SecurityTestStepResult result )
		{
			functionalTestLog.addSecurityTestFunctionalStepResult( result.getOriginalTestStepResult() );
			if( result.getOriginalTestStepResult().getStatus() == TestStepStatus.FAILED )
			{
				functionalStatus = ResultStatus.FAILED;
			}
			else if( result.getOriginalTestStepResult().getStatus() == TestStepStatus.OK
					&& functionalStatus != ResultStatus.FAILED )
			{
				functionalStatus = ResultStatus.OK;
			}
		}

		@Override
		public void afterSecurityScanRequest( TestCaseRunner testRunner, SecurityTestRunContext runContext,
				SecurityScanRequestResult securityCheckReqResult )
		{
			securityTestLog.addSecurityScanRequestResult( securityCheckReqResult );
		}

		@Override
		public void beforeStep( TestCaseRunner testRunner, SecurityTestRunContext runContext,
				TestStepResult testStepResult )
		{
			startStepLogEntryAdded = securityTestLog.addSecurityTestStepResult( testStepResult.getTestStep() );
		}

		@Override
		public void afterStep( TestCaseRunner testRunner, SecurityTestRunContext runContext, SecurityTestStepResult result )
		{
			boolean hasChecksToProcess = securityTest.getTestStepSecurityScansCount( result.getTestStep().getId() ) > 0;
			securityTestLog.updateSecurityTestStepResult( result, hasChecksToProcess, startStepLogEntryAdded );
			if( result.getStatus() == ResultStatus.FAILED )
			{
				securityStatus = ResultStatus.FAILED;
			}
			else if( result.getStatus() == ResultStatus.OK )
			{
				if( securityStatus != ResultStatus.FAILED )
					securityStatus = ResultStatus.OK;
			}
		}
	}
	
	@Override
	protected void renameModelItem()
	{
		SoapUI.getActionRegistry().performAction( "RenameSecurityTestAction", getModelItem(), null );
	}

	@Override
	protected void cloneModelItem()
	{
		SoapUI.getActionRegistry().performAction( "CloneSecurityTestAction", getModelItem(), null );		
	}
}
