/*******************************************************************************
 * Copyright (c) 2009 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.wst.dtd.ui.tests.viewer;

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

import junit.framework.TestCase;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.wst.dtd.core.internal.DTDNode;
import org.eclipse.wst.dtd.ui.internal.projection.DTDFoldingStrategy;
import org.eclipse.wst.dtd.ui.tests.ProjectUtil;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;

/**
 * <p>Tests that code folding annotations are correctly added/removed from DTD Documents</p>
 * <p>All of these tests use the same project and when possible the same open documents</p>
 * 
 * @see org.eclipse.wst.xml.ui.tests.XMLCodeFoldingTest Similar Test - XML Code Folding Test
 * @see org.eclipse.wst.css.ui.tests.viewer.CSSCodeFoldingTest Similar Test - CSS Code Folding Test
 * @see org.eclipse.wst.dtd.ui.tests.viewer.DTDCodeFoldingTest Similar Test - DTD Code Folding Test
 */
public class DTDCodeFoldingTest extends TestCase {
	/**
	 * The name of the reconciler job that adds the folding annotations to a <code>StructuredTextEditor</code>
	 */
	private static final String JOB_NAME_PROCESSING_DIRTY_REGIONS = "Processing Dirty Regions";
	
	private static final String WTP_AUTOTEST_NONINTERACTIVE = "wtp.autotest.noninteractive";
	private String previousWTPAutoTestNonInteractivePropValue = null;
	
	/**
	 * The name of the project that all of these tests will use
	 */
	private static final String PROJECT_NAME = "DTDCodeFoldingTest";
	
	/**
	 * The location of the testing files
	 */
	private static final String PROJECT_FILES = "/testresources/folding";
	
	/**
	 * the initial set up for these tests should only happen once
	 */
	private static boolean fIsSetup = false;
	
	/**
	 * After the last test the project that all of the tests were using should be deleted
	 */
	private static boolean fIsLastTest = false;
	
	/**
	 * The project that all of the tests use
	 */
	private static IProject fProject;
	
	/**
	 * Used to keep track of the already open editors so that the tests don't go through
	 * the trouble of opening the same editors over and over again
	 */
	private static Map fFileToEditorMap = new HashMap();
	
	/**
	 * Default constructor
	 */
	public DTDCodeFoldingTest() {
		super("DTDCodeFoldingTest");
	}
	
	/**
	 * Constructor that takes a test name.
	 * 
	 * @param name The name this test run should have.
	 */
	public DTDCodeFoldingTest(String name) {
		super(name);
	}
	
	/**
	 * This is run once before each test, some things should only happen once, others for each test
	 * 
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
		
		if(!fIsSetup) {
			fIsSetup = true;
			fIsLastTest = false;
			initializeResources();
		}
		
		String noninteractive = System.getProperty(WTP_AUTOTEST_NONINTERACTIVE);
		
		if (noninteractive != null) {
			previousWTPAutoTestNonInteractivePropValue = noninteractive;
		} else {
			previousWTPAutoTestNonInteractivePropValue = "false";
		}
		System.setProperty(WTP_AUTOTEST_NONINTERACTIVE, "true");
	}

	/**
	 * <p>This is run once after each test, some things should happen after each test,
	 * some only after the last test.</p>
	 * 
	 * <p><b>IMPORTANT:</b> Be sure that <code>fIsLastTest</code> is set to true at the end
	 * of the last test</p>
	 * 
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		super.tearDown();
		
		if(fIsLastTest) {
			fIsLastTest = false;
			fProject.delete(true, null);
		}
		
		if (previousWTPAutoTestNonInteractivePropValue != null) {
			System.setProperty(WTP_AUTOTEST_NONINTERACTIVE, previousWTPAutoTestNonInteractivePropValue);
		}
	}
	
	/**
	 * <p><b>TEST:</b> the initially placed folding annotations</p>
	 */
	public void testInitFolding() {
		IFile file = getFile("DTDFoldingTest1.dtd");
		StructuredTextEditor editor  = getEditor(file);
		
		String[] keyWords = {"entity1", "entity2", "entity3", "entity4", "entity5", "comment1"};
		waitForReconcileThenVerify(editor, keyWords);
	}
	
	/**
	 * <p><b>TEST:</b> that folding annotations are updated after node is removed</p>
	 */
	public void testRemoveNode() {
		IFile file = getFile("DTDFoldingTest1.dtd");
		
		StructuredTextEditor editor  = getEditor(file);
		
		try {
			//find the position to remove
			String[] initKeyWords = {"entity1"};
			List initExpectedPositions = getExpectedPositions(editor, initKeyWords);
			Position removalPos = (Position)initExpectedPositions.remove(0);
			
			//remove the position
			StructuredTextViewer viewer = editor.getTextViewer();
			IDocument doc = viewer.getDocument();
			doc.replace(removalPos.offset, removalPos.length, "");
			editor.doSave(null);
			
			//verify
			String[] keyWords = {"entity2", "entity3", "entity4", "entity5", "comment1"};
			waitForReconcileThenVerify(editor, keyWords);
		} catch(BadLocationException e) {
			fail("Test is broken, replace location is invalid.\n" + e.getMessage());
		}
	}
	
	/**
	 * <p><b>TEST:</b> that folding annotations are updated after node is added</p>
	 */
	public void testAddNode() {
		IFile file = getFile("DTDFoldingTest2.dtd");
		StructuredTextEditor editor  = getEditor(file);
		
		try {
			//find the position to add the new node after
			String[] initKeyWords = {"entity2"};
			List initExpectedPositions = getExpectedPositions(editor, initKeyWords);
			Position insertAfterPos = (Position)initExpectedPositions.get(0);
			
			//add the node
			StructuredTextViewer viewer = editor.getTextViewer();
			IDocument doc = viewer.getDocument();
			String newNodeText =
				"\r\n<!ATTLIST attlist1\r\n" +
				"%coreattrs;\t\t\t\t-- id, class, style, title --\r\n" +
				"lang\t%LanguageCode;\t#IMPLIED\t-- language code --\r\n" +
				"dir\t(ltr|rtl)\t#REQUIRED\t-- directionality --\r\n" +
				">\r\n";
			doc.replace(insertAfterPos.offset, 0, newNodeText);
			editor.doSave(null);
			
			//verify
			String[] keyWords = {"entity1", "entity2", "entity3", "entity4", "entity5", "comment1", "attlist1"};
			waitForReconcileThenVerify(editor, keyWords);
		} catch(BadLocationException e) {
			fail("Test is broken, add location is invalid.\n" + e.getMessage());
		}
		
		//TODO: move this to the last test in this file
		fIsLastTest = true;
	}
	
	/**
	 * Set up the project and workbench, this should only be done once
	 */
	private void initializeResources() {
		fProject = ProjectUtil.createProject(PROJECT_NAME, null, null);
		ProjectUtil.copyBundleEntriesIntoWorkspace(PROJECT_FILES, PROJECT_NAME);
	}
	
	/**
	 * <p>Given a file name in <code>fProject</code> attempts to get an <code>IFile</code>
	 * for it, if the file doesn't exist the test fails.</p>
	 * 
	 * @param name the name of the file to get
	 * @return the <code>IFile</code> associated with the given <code>name</code>
	 */
	private static IFile getFile(String name) {
		IFile file = fProject.getFile(name);
		assertTrue("Test file " + file + " can not be found", file.exists());
		
		return file;
	}
	
	/**
	 * <p>Given a <code>file</code> get an editor for it. If an editor has already
	 * been retrieved for the given <code>file</code> then return the same already
	 * open editor.</p>
	 * 
	 * @param file open and return an editor for this
	 * @return <code>StructuredTextEditor</code> opened from the given <code>file</code>
	 */
	private StructuredTextEditor getEditor(IFile file)  {
		StructuredTextEditor editor = (StructuredTextEditor)fFileToEditorMap.get(file);
		
		if(editor == null) {
			try {
				IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				IWorkbenchPage page = workbenchWindow.getActivePage();
				IEditorPart editorPart = IDE.openEditor(page, file, true, true);
				if(editorPart instanceof StructuredTextEditor) {
					editor = ((StructuredTextEditor)editorPart);
				} else {
					fail("Unable to open structured text editor");
				}
				
				if(editor != null) {
					fFileToEditorMap.put(file, editor);
				} else {
					fail("Could not open viewer for " + file);
				}
			} catch (Exception e) {
				fail("Could not open editor for " + file + " exception: " + e.getMessage());
			}
		}
		
		return editor;
	}
	
	/**
	 * Waits for the dirty region reconciler to finish and then verifies that only and all
	 * of the <code>expectedPositions</code> have folding annotations in the given <code>viewer</code>
	 * 
	 * @param viewer check for annotations at the given <code>expectedPositions</code>
	 * in here after the dirty region reconciler job has finished
	 * @param keyWords check for annotations at the positions that these key words are in,
	 * in the given <code>viewer</code> after the dirty region reconciler job has finished
	 */
	private void waitForReconcileThenVerify(StructuredTextEditor editor, String[] keyWords) {
		Job[] jobs = Job.getJobManager().find(null);
		Job job =  null;
		for(int i = 0; i < jobs.length && job == null; ++i) {
			if(jobs[i].getName().equals(JOB_NAME_PROCESSING_DIRTY_REGIONS)) {
				job = jobs[i];
			}
		}
		
		try {
			if(job != null) {
				//wait for dirty region reconciler job to finish before verifying annotations
				job.join();
			}
			
			//wait over, now verify
			List expectedPositions = getExpectedPositions(editor, keyWords);
			verifyAnnotationPositions(editor.getTextViewer(), expectedPositions);
		} catch (InterruptedException e) {
			fail("Could not join job " + job + "\n" + e.getMessage());
		}
	}
	
	/**
	 * Verifies that only and all of the <code>expectedPositions</code> have folding annotations
	 * in the given <code>viewer</code>
	 * 
	 * @param viewer check for annotations at the given <code>expectedPositions</code> in here 
	 * @param expectedPositions check for annotations at these positions in the given <code>viewer</code>
	 */
	private void verifyAnnotationPositions(StructuredTextViewer viewer, List expectedPositions) {
		ProjectionAnnotationModel projectionModel = viewer.getProjectionAnnotationModel();
		Iterator annotationIter = projectionModel.getAnnotationIterator();
		
		while(annotationIter.hasNext()) {
			Object obj = annotationIter.next();
			if(obj instanceof ProjectionAnnotation) {
				ProjectionAnnotation annotation = (ProjectionAnnotation)obj;
				Position pos = projectionModel.getPosition(annotation);
				
				boolean found = expectedPositions.remove(pos);
				
				/**
				 * Ignore folding regions with length of 0 because
				 * there are still some issues with DTD folding that can
				 * leave these behind when removed
				 */
				assertTrue("Position " + pos + " is not one of the expected positions", found || pos.length == 0);
			}
		}
		
		if(expectedPositions.size() != 0 ) {
			Iterator iter = expectedPositions.iterator();
			String message = "The following expected folding annotatinos could not be found:";
			while(iter.hasNext()) {
				message += "\n\t" + iter.next();
			}
			fail(message);
		}
	}
	
	/**
	 * <p>Searches the document associated with the given {@link StructuredTextEditor} for each
	 * of the given <code>keyWords</code> and then uses the logic from the folding strategy
	 * to determine the expected position of a folding annotation.</p>
	 * 
	 * <p><b>NOTE:</b> see {@link #calcFoldPosition(IndexedRegion)} for an important note</p>
	 * 
	 * @param editor the {@link StructuredTextEditor} to search for the given <code>keyWords</code>
	 * @param keyWords a list of text markers in regions that should have a folding annotations
	 * 
	 * @return the {@link Position}s that there should be folding annotations on based on the
	 * given <code>keyWords</code>
	 */
	private List getExpectedPositions(StructuredTextEditor editor, String[] keyWords) {
		List expectedPositions = new ArrayList(keyWords.length);
		
		IDocument doc = editor.getTextViewer().getDocument();
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(doc);
		IStructuredDocument structuredDoc = model.getStructuredDocument();
		String text = structuredDoc.getText();
		
		for(int i = 0; i < keyWords.length; ++i) {
			int offsetOfKeyword = text.indexOf(keyWords[i]);
			IndexedRegion indexedRegion = model.getIndexedRegion(offsetOfKeyword);

			Position pos = calcFoldPosition(indexedRegion);

			if(pos != null) {
				expectedPositions.add(pos);
			}
		}
		
		return expectedPositions;
	}
	
	/**
	 * <p>This is an almost exact copy of {@link DTDFoldingStrategy#calcNewFoldPosition}</p>
	 * 
	 * <p>This has to be done because these tests have to calculate the expected folding
	 * locations on the fly because different OSs end up with different character counts
	 * because of line endings</p>
	 * 
	 * <p>So unfortunately this logic is not really being tested by these tests, but the
	 * more complicated and more likely to break logic of updating/adding/etc folding
	 * locations is still being tested.</p>
	 * 
	 * @see DTDFoldingStrategy#calcNewFoldPosition
	 */
	private Position calcFoldPosition(IndexedRegion indexedRegion) {
		Position newPos = null;

		DTDNode node = (DTDNode)indexedRegion;
		int start = node.getStartOffset();
		int length = node.getEndOffset() - start;
		
		if(length > 0) {
			newPos = new Position(start,length);
		}

		return newPos;
	}
}
