/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.debug.tests.core;

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

import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.testplugin.ConsoleLineTracker;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.console.JavaExceptionHyperLink;
import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceHyperlink;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.console.IHyperlink;
import org.eclipse.ui.console.IOConsole;

/**
 * Tests console line tracker.
 */
public class LineTrackerTests extends AbstractDebugTest implements IConsoleLineTrackerExtension {
	
	protected String[] fLines = new String[] {
		"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"
	};
	
	protected IJavaDebugTarget fTarget;
	
	protected List<String> fLinesRead = new ArrayList<String>();
	
	protected boolean fStarted = false;
	
	protected boolean fStopped = false;
	
	protected IConsole fConsole = null;
	
	protected Object fLock = new Object();
	
	public LineTrackerTests(String name) {
		super(name);
	}
	
    @Override
	protected void setUp() throws Exception {
        super.setUp();
        fStarted = false;
        fStopped = false;
    }
    
    @Override
	protected void tearDown() throws Exception {
        // delete references and gc to free memory.
        fConsole = null;
        fLines = null;
        fLinesRead.clear();
        fLinesRead = null;
        
        System.gc();
		super.tearDown();
    }   
    
    
	public void testSimpleLineCounter() throws Exception {
		ConsoleLineTracker.setDelegate(this);
		fTarget = null;
		try {
			fTarget = launchAndTerminate("OneToTen");
			synchronized (fLock) {
			    if (!fStopped) {
			        fLock.wait(30000);
			    }
			}
			dumpOnError(11);
			assertTrue("Never received 'start' notification", fStarted);
			assertTrue("Never received 'stopped' notification", fStopped);
			// there are 10 lines and one "empty line" (i.e. the last "new line")
			assertEquals("Wrong number of lines output", 11, fLinesRead.size());
			for (int i = 0; i < 10; i++) {
				assertEquals("Line " + i + " not equal", fLines[i], fLinesRead.get(i));			
			}
			assertEquals("Should be an empty last line", IInternalDebugCoreConstants.EMPTY_STRING, fLinesRead.get(10));
		} finally {
			ConsoleLineTracker.setDelegate(null);
			terminateAndRemove(fTarget);
		}
	} 
	
	/**
	 * This program prints the final line without a new line
	 * @throws Exception
	 */
	public void testNoPrintln() throws Exception {
		ConsoleLineTracker.setDelegate(this);
		fTarget = null;
		try {
			fTarget = launchAndTerminate("OneToTenPrint");
			synchronized (fLock) {
			    if (!fStopped) {
			        fLock.wait(30000);
			    }
            }
			dumpOnError(10);
			assertTrue("Never received 'start' notification", fStarted);
			assertTrue("Did not receive 'stopped' notification", fStopped);
			assertEquals("Wrong number of lines", 10, fLinesRead.size());
			for (int i = 0; i < 10; i++) {
				assertEquals("Line " + i + " not equal", fLines[i], fLinesRead.get(i));			
			}
		} finally {
			ConsoleLineTracker.setDelegate(null);
			terminateAndRemove(fTarget);
		}
	} 
	
	/**
	 * Test 10,000 lines of output.
	 * 
	 * @throws Exception
	 */
	public void testFlood() throws Exception {
		ConsoleLineTracker.setDelegate(this);
		ILaunch launch = null;
		try {
			ILaunchConfiguration config = getLaunchConfiguration("FloodConsole");
			assertNotNull("Could not locate launch configuration", config);
			launch = config.launch(ILaunchManager.RUN_MODE, null);
			
			synchronized (fLock) {
			    if (!fStopped) {
			        fLock.wait(480000);
			    }
			}
			assertTrue("Never received 'start' notification", fStarted);
			assertTrue("Never received 'stopped' notification", fStopped);
			// Should be 10,000 lines
			assertEquals("Wrong number of lines", 10000, fLinesRead.size());
		} finally {
			ConsoleLineTracker.setDelegate(null);
			launch.getProcesses()[0].terminate();
			DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
		}
	} 	
	
	public void testHyperLink() throws Exception {
	    try {
			ConsoleLineTracker.setDelegate(this);
			fTarget = launchAndTerminate("ThrowsNPE");
			getHyperlink(0, ConsoleLineTracker.getDocument());
	    } finally {
	        ConsoleLineTracker.setDelegate(null);
	        terminateAndRemove(fTarget);
	    }
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#dispose()
	 */
	@Override
	public void dispose() {
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#init(org.eclipse.debug.ui.console.IConsole)
	 */
	@Override
	public void init(IConsole console) {
		fConsole = console;
		fStarted = true;
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#lineAppended(org.eclipse.jface.text.IRegion)
	 */
	@Override
	public void lineAppended(IRegion line) {
		if (fStarted) {
			try {
				String text = fConsole.getDocument().get(line.getOffset(), line.getLength());
				fLinesRead.add(text);
			} catch (BadLocationException e) {
			    e.printStackTrace();
			}
		}
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#streamClosed()
	 */
	@Override
	public void consoleClosed() {
	    synchronized (fLock) {
			fStopped = true;
			fLock.notifyAll();
        }
	}
	
	/**
	 * Tests that stack traces appear with hyperlinks
	 */
	public void testStackTraces() throws Exception {
		ConsoleLineTracker.setDelegate(this);
		fTarget = null;
		IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
		boolean suspendOnException = jdiUIPreferences.getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS);
		jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false);
		try {
			fTarget = launchAndTerminate("StackTraces");
			synchronized (fLock) {
			    if (!fStopped) {
			        fLock.wait(30000);
			    }
			}
			assertTrue("Never received 'start' notification", fStarted);
			assertTrue("Never received 'stopped' notification", fStopped);
			assertTrue("Console should be an IOCosnole", fConsole instanceof IOConsole);
			IOConsole console = (IOConsole)fConsole;
			IHyperlink[] hyperlinks = console.getHyperlinks();
			// should be 100 exception hyperlinks
			int total = 0;
			for (int i = 0; i < hyperlinks.length; i++) {
                IHyperlink hyperlink = hyperlinks[i];
                if (hyperlink instanceof JavaExceptionHyperLink) {
                    total++;
                    // should be followed by a stack trace hyperlink
                    assertTrue("Stack trace hyperlink missing", hyperlinks[i + 1] instanceof JavaStackTraceHyperlink);
                }
            }
			assertEquals("Wrong number of exception hyperlinks", 100, total);
		} finally {
			ConsoleLineTracker.setDelegate(null);
			jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, suspendOnException);
			terminateAndRemove(fTarget);
		}	    
	}
	
	public void testStringConcatenation() throws Exception {
	    ConsoleLineTracker.setDelegate(this);
	    String typeName = "PrintConcatenation";
	    createConditionalLineBreakpoint(20, typeName, "System.out.println(\"var = \" + foo); return false;", true);
	    fTarget = null;
	    try {
	        fTarget = launchAndTerminate(typeName);
	        synchronized (fLock) {
			    if (!fStopped) {
			        fLock.wait(30000);
			    }
			}
	        dumpOnError(2);
	        assertTrue("Never received 'start' notification", fStarted);
			assertTrue("Never received 'stopped' notification", fStopped);
			assertEquals("Wrong number of lines output", 2, fLinesRead.size());
			assertEquals("Wrong output", "var = foo", fLinesRead.get(0));
	    } finally {
	        ConsoleLineTracker.setDelegate(null);
	        removeAllBreakpoints();
	        terminateAndRemove(fTarget);
	    }
	}
	
	public void testIntConcatenation() throws Exception {
	    ConsoleLineTracker.setDelegate(this);
	    String typeName = "PrintConcatenation";
	    createConditionalLineBreakpoint(20, typeName, "System.out.println(\"var = \" + x); return false;", true);
	    fTarget = null;
	    try {
	        fTarget = launchAndTerminate(typeName);
	        synchronized (fLock) {
			    if (!fStopped) {
			        fLock.wait(30000);
			    }
			}
	        dumpOnError(2);
	        assertTrue("Never received 'start' notification", fStarted);
			assertTrue("Never received 'stopped' notification", fStopped);
			assertEquals("Wrong number of lines output", 2, fLinesRead.size());
			assertEquals("Wrong output", "var = 35", fLinesRead.get(0));
	    } finally {
	        ConsoleLineTracker.setDelegate(null);
	        removeAllBreakpoints();
	        terminateAndRemove(fTarget);
	    }
	}
	
	private void dumpOnError(int expectedLines) {
        if (fLinesRead.size() != expectedLines) {
	    	Iterator<String> lines = fLinesRead.iterator();
	    	while (lines.hasNext()) {
				String line = lines.next();
				System.out.println(line);
			}
        }
	}
}
