package junit.swingui;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.URL;
import java.util.*;

import javax.swing.*;
import javax.swing.event.*;
import junit.framework.*;
import junit.runner.*;

/**
 * A Swing based user interface to run tests.
 * Enter the name of a class which either provides a static
 * suite method or is a subclass of TestCase.
 * <pre>
 * Synopsis: java junit.swingui.TestRunner [-noloading] [TestCase]
 * </pre>
 * TestRunner takes as an optional argument the name of the testcase class to be run.
 */
public class TestRunner extends BaseTestRunner implements TestRunContext {
	private static final int GAP= 4;
	private static final int HISTORY_LENGTH= 5;

	protected JFrame fFrame;
	private Thread fRunner;
	private TestResult fTestResult;

	private JComboBox fSuiteCombo;
	private ProgressBar fProgressIndicator;
	private DefaultListModel fFailures;
	private JLabel fLogo;
	private CounterPanel fCounterPanel;
	private JButton fRun;
	private JButton fQuitButton;
	private JButton fRerunButton;
	private StatusLine fStatusLine;
	private FailureDetailView fFailureView;
	private JTabbedPane fTestViewTab;
	private JCheckBox fUseLoadingRunner;
	private Vector fTestRunViews= new Vector(); // view associated with tab in tabbed pane

	private static final String TESTCOLLECTOR_KEY= "TestCollectorClass";
	private static final String FAILUREDETAILVIEW_KEY= "FailureViewClass";

	public TestRunner() {
	}

	public static void main(String[] args) {
		new TestRunner().start(args);
	}

	public static void run(Class test) {
		String args[]= { test.getName() };
		main(args);
	}

	public void testFailed(final int status, final Test test, final Throwable t) {
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					switch (status) {
						case TestRunListener.STATUS_ERROR:
							fCounterPanel.setErrorValue(fTestResult.errorCount());
							appendFailure(test, t);
							break;
						case TestRunListener.STATUS_FAILURE:
							fCounterPanel.setFailureValue(fTestResult.failureCount());
							appendFailure(test, t);
							break;
					}
				}
			}
		);
	}

	public void testStarted(String testName) {
		postInfo("Running: "+testName);
	}

	public void testEnded(String stringName) {
		synchUI();
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					if (fTestResult != null) {
						fCounterPanel.setRunValue(fTestResult.runCount());
						fProgressIndicator.step(fTestResult.runCount(), fTestResult.wasSuccessful());
					}
				}
			}
		);
	}

	public void setSuite(String suiteName) {
		fSuiteCombo.getEditor().setItem(suiteName);
	}

	private void addToHistory(final String suite) {
		for (int i= 0; i < fSuiteCombo.getItemCount(); i++) {
			if (suite.equals(fSuiteCombo.getItemAt(i))) {
				fSuiteCombo.removeItemAt(i);
				fSuiteCombo.insertItemAt(suite, 0);
				fSuiteCombo.setSelectedIndex(0);
				return;
			}
		}
		fSuiteCombo.insertItemAt(suite, 0);
		fSuiteCombo.setSelectedIndex(0);
		pruneHistory();
	}

	private void pruneHistory() {
		int historyLength= getPreference("maxhistory", HISTORY_LENGTH);
		if (historyLength < 1)
			historyLength= 1;
		for (int i= fSuiteCombo.getItemCount()-1; i > historyLength-1; i--)
			fSuiteCombo.removeItemAt(i);
	}

	private void appendFailure(Test test, Throwable t) {
		fFailures.addElement(new TestFailure(test, t));
		if (fFailures.size() == 1)
			revealFailure(test);
	}

	private void revealFailure(Test test) {
		for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) {
			TestRunView v= (TestRunView) e.nextElement();
			v.revealFailure(test);
		}
	}

	protected void aboutToStart(final Test testSuite) {
		for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) {
			TestRunView v= (TestRunView) e.nextElement();
			v.aboutToStart(testSuite, fTestResult);
		}
	}

	protected void runFinished(final Test testSuite) {
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) {
						TestRunView v= (TestRunView) e.nextElement();
						v.runFinished(testSuite, fTestResult);
					}
				}
			}
		);
	}

	protected CounterPanel createCounterPanel() {
		return new CounterPanel();
	}

	protected JPanel createFailedPanel() {
		JPanel failedPanel= new JPanel(new GridLayout(0, 1, 0, 2));
		fRerunButton= new JButton("Run");
		fRerunButton.setEnabled(false);
		fRerunButton.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					rerun();
				}
			}
		);
		failedPanel.add(fRerunButton);
		return failedPanel;
	}

	protected FailureDetailView createFailureDetailView() {
		String className= BaseTestRunner.getPreference(FAILUREDETAILVIEW_KEY);
		if (className != null) {
			Class viewClass= null;
			try {
				viewClass= Class.forName(className);
				return (FailureDetailView)viewClass.newInstance();
			} catch(Exception e) {
				JOptionPane.showMessageDialog(fFrame, "Could not create Failure DetailView - using default view");
			}
		}
		return new DefaultFailureDetailView();
	}

	/**
	 * Creates the JUnit menu. Clients override this
	 * method to add additional menu items.
	 */
	protected JMenu createJUnitMenu() {
		JMenu menu= new JMenu("JUnit");
		menu.setMnemonic('J');
		JMenuItem mi1= new JMenuItem("About...");
		mi1.addActionListener(
		    new ActionListener() {
		        public void actionPerformed(ActionEvent event) {
		            about();
		        }
		    }
		);
		mi1.setMnemonic('A');
		menu.add(mi1);

		menu.addSeparator();
		JMenuItem mi2= new JMenuItem(" Exit ");
		mi2.addActionListener(
		    new ActionListener() {
		        public void actionPerformed(ActionEvent event) {
		            terminate();
		        }
		    }
		);
		mi2.setMnemonic('x');
		menu.add(mi2);

		return menu;
	}

	protected JFrame createFrame() {
		JFrame frame= new JFrame("JUnit");
		Image icon= loadFrameIcon();
		if (icon != null)
			frame.setIconImage(icon);
		frame.getContentPane().setLayout(new BorderLayout(0, 0));

		frame.addWindowListener(
			new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					terminate();
				}
			}
		);
		return frame;
	}

	protected JLabel createLogo() {
		JLabel label;
		Icon icon= getIconResource(BaseTestRunner.class, "logo.gif");
		if (icon != null)
			label= new JLabel(icon);
		else
			label= new JLabel("JV");
		label.setToolTipText("JUnit Version "+Version.id());
		return label;
	}

	protected void createMenus(JMenuBar mb) {
		mb.add(createJUnitMenu());
	}

	protected JCheckBox createUseLoaderCheckBox() {
		boolean useLoader= useReloadingTestSuiteLoader();
		JCheckBox box= new JCheckBox("Reload classes every run", useLoader);
		box.setToolTipText("Use a custom class loader to reload the classes for every run");
		if (inVAJava())
			box.setVisible(false);
		return box;
	}

	protected JButton createQuitButton() {
		 // spaces required to avoid layout flicker
		 // Exit is shorter than Stop that shows in the same column
		JButton quit= new JButton(" Exit ");
		quit.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					terminate();
				}
			}
		);
		return quit;
	}

	protected JButton createRunButton() {
		JButton run= new JButton("Run");
		run.setEnabled(true);
		run.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					runSuite();
				}
			}
		);
		return run;
	}

	protected Component createBrowseButton() {
		JButton browse= new JButton("...");
		browse.setToolTipText("Select a Test class");
		browse.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					browseTestClasses();
				}
			}
		);
		return browse;
	}

	protected StatusLine createStatusLine() {
		return new StatusLine(380);
	}

	protected JComboBox createSuiteCombo() {
		JComboBox combo= new JComboBox();
		combo.setEditable(true);
		combo.setLightWeightPopupEnabled(false);

		combo.getEditor().getEditorComponent().addKeyListener(
			new KeyAdapter() {
				public void keyTyped(KeyEvent e) {
					textChanged();
					if (e.getKeyChar() == KeyEvent.VK_ENTER)
						runSuite();
				}
			}
		);
		try {
			loadHistory(combo);
		} catch (IOException e) {
			// fails the first time
		}
		combo.addItemListener(
			new ItemListener() {
				public void itemStateChanged(ItemEvent event) {
					if (event.getStateChange() == ItemEvent.SELECTED) {
						textChanged();
					}
				}
			}
		);
		return combo;
	}

	protected JTabbedPane createTestRunViews() {
		JTabbedPane pane= new JTabbedPane(JTabbedPane.BOTTOM);

		FailureRunView lv= new FailureRunView(this);
		fTestRunViews.addElement(lv);
		lv.addTab(pane);

		TestHierarchyRunView tv= new TestHierarchyRunView(this);
		fTestRunViews.addElement(tv);
		tv.addTab(pane);

		pane.addChangeListener(
			new ChangeListener() {
				public void stateChanged(ChangeEvent e) {
					testViewChanged();
				}
			}
		);
		return pane;
	}

	public void testViewChanged() {
		TestRunView view= (TestRunView)fTestRunViews.elementAt(fTestViewTab.getSelectedIndex());
		view.activate();
	}

	protected TestResult createTestResult() {
		return new TestResult();
	}

	protected JFrame createUI(String suiteName) {
		JFrame frame= createFrame();
		JMenuBar mb= new JMenuBar();
		createMenus(mb);
		frame.setJMenuBar(mb);

		JLabel suiteLabel= new JLabel("Test class name:");
		fSuiteCombo= createSuiteCombo();
		fRun= createRunButton();
		frame.getRootPane().setDefaultButton(fRun);
		Component browseButton= createBrowseButton();

		fUseLoadingRunner= createUseLoaderCheckBox();
		fProgressIndicator= new ProgressBar();
		fCounterPanel= createCounterPanel();

		fFailures= new DefaultListModel();

		fTestViewTab= createTestRunViews();
		JPanel failedPanel= createFailedPanel();

		fFailureView= createFailureDetailView();
		JScrollPane tracePane= new JScrollPane(fFailureView.getComponent(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

		fStatusLine= createStatusLine();
		fQuitButton= createQuitButton();
		fLogo= createLogo();

		JPanel panel= new JPanel(new GridBagLayout());

		addGrid(panel, suiteLabel,	0, 0, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
		addGrid(panel, fSuiteCombo, 	0, 1, 1, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
		addGrid(panel, browseButton, 	1, 1, 1, GridBagConstraints.NONE, 			0.0, GridBagConstraints.WEST);
		addGrid(panel, fRun, 		2, 1, 1, GridBagConstraints.HORIZONTAL, 	0.0, GridBagConstraints.CENTER);

		addGrid(panel, fUseLoadingRunner,  	0, 2, 3, GridBagConstraints.NONE, 1.0, GridBagConstraints.WEST);
		//addGrid(panel, new JSeparator(), 	0, 3, 3, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST);


		addGrid(panel, fProgressIndicator, 	0, 3, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
		addGrid(panel, fLogo, 			2, 3, 1, GridBagConstraints.NONE, 			0.0, GridBagConstraints.NORTH);

		addGrid(panel, fCounterPanel,	 0, 4, 2, GridBagConstraints.NONE, 			0.0, GridBagConstraints.WEST);
		addGrid(panel, new JSeparator(), 	0, 5, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST);
		addGrid(panel, new JLabel("Results:"),	0, 6, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);

		JSplitPane splitter= new JSplitPane(JSplitPane.VERTICAL_SPLIT, fTestViewTab, tracePane);
		addGrid(panel, splitter, 	 0, 7, 2, GridBagConstraints.BOTH, 			1.0, GridBagConstraints.WEST);

		addGrid(panel, failedPanel, 	 2, 7, 1, GridBagConstraints.HORIZONTAL, 	0.0, GridBagConstraints.NORTH/*CENTER*/);

		addGrid(panel, fStatusLine, 	 0, 9, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.CENTER);
		addGrid(panel, fQuitButton, 	 2, 9, 1, GridBagConstraints.HORIZONTAL, 	0.0, GridBagConstraints.CENTER);

		frame.setContentPane(panel);
		frame.pack();
		frame.setLocation(200, 200);
		return frame;
	}

	private void addGrid(JPanel p, Component co, int x, int y, int w, int fill, double wx, int anchor) {
		GridBagConstraints c= new GridBagConstraints();
		c.gridx= x; c.gridy= y;
		c.gridwidth= w;
		c.anchor= anchor;
		c.weightx= wx;
		c.fill= fill;
		if (fill == GridBagConstraints.BOTH || fill == GridBagConstraints.VERTICAL)
			c.weighty= 1.0;
		c.insets= new Insets(y == 0 ? 10 : 0, x == 0 ? 10 : GAP, GAP, GAP); 
		p.add(co, c);
	}

	protected String getSuiteText() {
		if (fSuiteCombo == null)
			return "";
		return (String)fSuiteCombo.getEditor().getItem();
	}

	public ListModel getFailures() {
		return fFailures;
	}

	public void insertUpdate(DocumentEvent event) {
		textChanged();
	}

	public void browseTestClasses() {
		TestCollector collector= createTestCollector();
		TestSelector selector= new TestSelector(fFrame, collector);
		if (selector.isEmpty()) {
			JOptionPane.showMessageDialog(fFrame, "No Test Cases found.\nCheck that the configured \'TestCollector\' is supported on this platform.");
			return;
		}
		selector.show();
		String className= selector.getSelectedItem();
		if (className != null)
			setSuite(className);
	}

	TestCollector createTestCollector() {
		String className= BaseTestRunner.getPreference(TESTCOLLECTOR_KEY);
		if (className != null) {
			Class collectorClass= null;
			try {
				collectorClass= Class.forName(className);
				return (TestCollector)collectorClass.newInstance();
			} catch(Exception e) {
				JOptionPane.showMessageDialog(fFrame, "Could not create TestCollector - using default collector");
			}
		}
		return new SimpleTestCollector();
	}

	private Image loadFrameIcon() {
		ImageIcon icon= (ImageIcon)getIconResource(BaseTestRunner.class, "smalllogo.gif");
		if (icon != null)
			return icon.getImage();
		return null;
	}

	private void loadHistory(JComboBox combo) throws IOException {
		BufferedReader br= new BufferedReader(new FileReader(getSettingsFile()));
		int itemCount= 0;
		try {
			String line;
			while ((line= br.readLine()) != null) {
				combo.addItem(line);
				itemCount++;
			}
			if (itemCount > 0)
				combo.setSelectedIndex(0);

		} finally {
			br.close();
		}
	}

	private File getSettingsFile() {
	 	String home= System.getProperty("user.home");
 		return new File(home,".junitsession");
 	}

	private void postInfo(final String message) {
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					showInfo(message);
				}
			}
		);
	}

	private void postStatus(final String status) {
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					showStatus(status);
				}
			}
		);
	}

	public void removeUpdate(DocumentEvent event) {
		textChanged();
	}

	private void rerun() {
		TestRunView view= (TestRunView)fTestRunViews.elementAt(fTestViewTab.getSelectedIndex());
		Test rerunTest= view.getSelectedTest();
		if (rerunTest != null)
			rerunTest(rerunTest);
	}

	private void rerunTest(Test test) {
		if (!(test instanceof TestCase)) {
			showInfo("Could not reload "+ test.toString());
			return;
		}
		Test reloadedTest= null;
		TestCase rerunTest= (TestCase)test;

		try {
			Class reloadedTestClass= getLoader().reload(test.getClass()); 
			reloadedTest= TestSuite.createTest(reloadedTestClass, rerunTest.getName());
		} catch(Exception e) {
			showInfo("Could not reload "+ test.toString());
			return;
		}
		TestResult result= new TestResult();
		reloadedTest.run(result);

		String message= reloadedTest.toString();
		if(result.wasSuccessful())
			showInfo(message+" was successful");
		else if (result.errorCount() == 1)
			showStatus(message+" had an error");
		else
			showStatus(message+" had a failure");
	}

	protected void reset() {
		fCounterPanel.reset();
		fProgressIndicator.reset();
		fRerunButton.setEnabled(false);
		fFailureView.clear();
		fFailures.clear();
	}

	protected void runFailed(String message) {
		showStatus(message);
		fRun.setText("Run");
		fRunner= null;
	}

	synchronized public void runSuite() {
		if (fRunner != null) {
			fTestResult.stop();
		} else {
			setLoading(shouldReload());
			reset();
			showInfo("Load Test Case...");
			final String suiteName= getSuiteText();
			final Test testSuite= getTest(suiteName);
			if (testSuite != null) {
				addToHistory(suiteName);
				doRunTest(testSuite);
			}
		}
	}

	private boolean shouldReload() {
		return !inVAJava() && fUseLoadingRunner.isSelected();
	}


	synchronized protected void runTest(final Test testSuite) {
		if (fRunner != null) {
			fTestResult.stop();
		} else {
			reset();
			if (testSuite != null) {
				doRunTest(testSuite);
			}
		}
	}

	private void doRunTest(final Test testSuite) {
		setButtonLabel(fRun, "Stop");
		fRunner= new Thread("TestRunner-Thread") {
			public void run() {
				TestRunner.this.start(testSuite);
				postInfo("Running...");

				long startTime= System.currentTimeMillis();
				testSuite.run(fTestResult);

				if (fTestResult.shouldStop()) {
					postStatus("Stopped");
				} else {
					long endTime= System.currentTimeMillis();
					long runTime= endTime-startTime;
					postInfo("Finished: " + elapsedTimeAsString(runTime) + " seconds");
				}
				runFinished(testSuite);
				setButtonLabel(fRun, "Run");
				fRunner= null;
				System.gc();
			}
		};
		// make sure that the test result is created before we start the
		// test runner thread so that listeners can register for it.
		fTestResult= createTestResult();
		fTestResult.addListener(TestRunner.this);
		aboutToStart(testSuite);

		fRunner.start();
	}

	private void saveHistory() throws IOException {
		BufferedWriter bw= new BufferedWriter(new FileWriter(getSettingsFile()));
		try {
			for (int i= 0; i < fSuiteCombo.getItemCount(); i++) {
				String testsuite= fSuiteCombo.getItemAt(i).toString();
				bw.write(testsuite, 0, testsuite.length());
				bw.newLine();
			}
		} finally {
			bw.close();
		}
	}

	private void setButtonLabel(final JButton button, final String label) {
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					button.setText(label);
				}
			}
		);
	}

	public void handleTestSelected(Test test) {
		fRerunButton.setEnabled(test != null && (test instanceof TestCase));
		showFailureDetail(test);
	}

	private void showFailureDetail(Test test) {
		if (test != null) {
			ListModel failures= getFailures();
			for (int i= 0; i < failures.getSize(); i++) {
				TestFailure failure= (TestFailure)failures.getElementAt(i);
				if (failure.failedTest() == test) {
					fFailureView.showFailure(failure);
					return;
				}
			}
		}
		fFailureView.clear();
	}

	private void showInfo(String message) {
		fStatusLine.showInfo(message);
	}

	private void showStatus(String status) {
		fStatusLine.showError(status);
	}

	/**
	 * Starts the TestRunner
	 */
	public void start(String[] args) {
		String suiteName= processArguments(args);
		fFrame= createUI(suiteName);
		fFrame.pack();
		fFrame.setVisible(true);

		if (suiteName != null) {
			setSuite(suiteName);
			runSuite();
		}
	}

	private void start(final Test test) {
		SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					int total= test.countTestCases();
					fProgressIndicator.start(total);
					fCounterPanel.setTotal(total);
				}
			}
		);
	}

	/**
	 * Wait until all the events are processed in the event thread
	 */
	private void synchUI() {
		try {
			SwingUtilities.invokeAndWait(
				new Runnable() {
					public void run() {}
				}
			);
		}
		catch (Exception e) {
		}
	}

	/**
	 * Terminates the TestRunner
	 */
	public void terminate() {
		fFrame.dispose();
		try {
			saveHistory();
		} catch (IOException e) {
			System.out.println("Couldn't save test run history");
		}
		System.exit(0);
	}

	public void textChanged() {
		fRun.setEnabled(getSuiteText().length() > 0);
		clearStatus();
	}

	protected void clearStatus() {
		fStatusLine.clear();
	}

	public static Icon getIconResource(Class clazz, String name) {
		URL url= clazz.getResource(name);
		if (url == null) {
			System.err.println("Warning: could not load \""+name+"\" icon");
			return null;
		}
		return new ImageIcon(url);
	}

	private void about() {
		AboutDialog about= new AboutDialog(fFrame);
		about.show();
	}
}