package org.eclipse.wst.xml.core.tests.document;

import java.io.File;
import java.io.IOException;

import junit.framework.TestCase;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.Position;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.xml.core.internal.modelhandler.XMLModelLoader;
import org.eclipse.wst.xml.core.tests.util.FileUtil;
import org.eclipse.wst.xml.core.tests.util.ProjectUnzipUtility;

public class TestStructuredDocument extends TestCase {

	class TestListener implements IStructuredDocumentListener {

		boolean newModelCalled = false;
		boolean noChangeCalled = false;
		boolean nodesReplacedCalled = false;
		boolean regionChangedCalled = false;
		boolean regionsReplacedCalled = false;

		public void newModel(NewDocumentEvent structuredDocumentEvent) {
			newModelCalled = true;
		}

		public void noChange(NoChangeEvent structuredDocumentEvent) {
			noChangeCalled = true;
		}

		public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
			nodesReplacedCalled = true;
		}

		public void regionChanged(RegionChangedEvent structuredDocumentEvent) {
			regionChangedCalled = true;
		}

		public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {
			regionsReplacedCalled = true;
		}
	}

	private boolean isSetup = false;
	private XMLModelLoader fLoader = null;

	private final String fProjectName = "DOCUMENT-LOADER";
	private final String fZipFileName = "xml-document-loader-tests.zip";

	public TestStructuredDocument() {
		super("TestStructuredDocument");
	}

	protected void setUp() throws Exception {

		super.setUp();
		if (!this.isSetup) {
			fLoader = new XMLModelLoader();
			doSetup();
			this.isSetup = true;
		}
	}

	private void doSetup() throws Exception {

		// root of workspace directory
		Location platformLocation = Platform.getInstanceLocation();

		ProjectUnzipUtility unzipUtil = new ProjectUnzipUtility();
		File zipFile = FileUtil.makeFileFor(ProjectUnzipUtility.PROJECT_ZIPS_FOLDER, fZipFileName, ProjectUnzipUtility.PROJECT_ZIPS_FOLDER);
		unzipUtil.unzipAndImport(zipFile, platformLocation.getURL().getFile());
		unzipUtil.initJavaProject(fProjectName);
	}

	/**
	 * Be sure to release any models obtained from this method.
	 * 
	 */
	IStructuredModel getTestModel() throws IOException, CoreException {

		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(fProjectName);
		IFile iFile = (IFile) project.findMember("/files/simple.xml");
		// fProjectName + "/files/simple.xml"


		IStructuredModel model = null;
		IModelManager modelManager = StructuredModelManager.getModelManager();

		model = modelManager.getModelForEdit(iFile);


		return model;

	}



	public void testDocumentChangingListener() throws BadLocationException, IOException, CoreException {
		// TODO: may need to fake events to really tests this

		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();

			TestListener listener = new TestListener();

			sDoc.addDocumentChangingListener(listener);
			String text = sDoc.get();
			sDoc.replace(0, text.length(), text);

			sDoc.removeDocumentChangingListener(listener);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testReadOnly() throws IOException, CoreException {

		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			String text = sDoc.get();

			sDoc.clearReadOnly(0, text.length());
			assertFalse(sDoc.containsReadOnly(0, text.length()));

			sDoc.makeReadOnly(0, 10);
			assertTrue(sDoc.containsReadOnly(9, 1));
			assertTrue(sDoc.containsReadOnly(0, text.length()));

			sDoc.clearReadOnly(0, text.length());
			assertFalse(sDoc.containsReadOnly(0, text.length()));
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testGetRegionAtCharacterOffset() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			IStructuredDocumentRegion r = sDoc.getRegionAtCharacterOffset(0);
			assertNotNull("couldn't get region at offset: 0", r);

			r = sDoc.getRegionAtCharacterOffset(sDoc.getLength());
			assertNotNull("couldn't get region at offset: " + sDoc.getLength(), r);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}

		}
	}

	public void testGetRegionList() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			IStructuredDocumentRegionList regions = sDoc.getRegionList();
			assertNotNull("couldn't get region list", regions);
			assertEquals(17, regions.getLength());
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testGetText() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			String text = sDoc.getText();
			String expectedText = "<?xml version=\"1.0\"?>\r\n<list>\r\n\t<item1 attr1=\"attr1\" attr2=\"attr2\" attr3=\"attr3\">\r\n\t\tone\r\n\t</item1>\r\n\t<item2 attr1=\"attr1\" attr2=\"attr2\" attr3=\"attr3\" >\r\n\t\ttwo\r\n\t</item2>\r\n\t<item3 attr1=\"attr1\" attr2=\"attr2\" attr3=\"attr3\">\r\n\t\tthree\r\n\t</item3>\r\n</list>";
			assertEquals(expectedText, text);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testNewInstance() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			IStructuredDocument newDoc = sDoc.newInstance();
			assertNotSame("document instances should be different", sDoc, newDoc);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testReplaceText() throws BadLocationException, IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			sDoc.replace(0, sDoc.getLength(), "replaced");

			String text = sDoc.getText();
			assertEquals("replaced", text);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testOverrideReadOnlyReplaceText() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			sDoc.makeReadOnly(0, 1);
			sDoc.replaceText(this, 0, sDoc.getLength(), "replaced");
			assertNotSame("text should not have been replacable (read only)", "replaced", sDoc.getText());

			sDoc.replaceText(this, 0, sDoc.getLength(), "replaced", true);
			assertEquals("text should have been forced replaced", "replaced", sDoc.getText());
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testSetText() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			sDoc.setText(this, "set text");

			assertEquals("set text failed", "set text", sDoc.getText());
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testGetEncodingMemento() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = null;
			sDoc = model.getStructuredDocument();
			EncodingMemento memento = sDoc.getEncodingMemento();
			assertNotNull("couldn't get encoding memento", memento);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testGetDetectedLineDelimiter() throws IOException, CoreException {
		String platformDelimiter = System.getProperty("line.separator");
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			String delim = sDoc.getLineDelimiter();
			assertEquals("wrong preferred line delmiter", platformDelimiter, delim);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testSetEncodingMemento() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			EncodingMemento memento = new EncodingMemento();
			sDoc.setEncodingMemento(memento);
			EncodingMemento gottenMemento = sDoc.getEncodingMemento();
			assertEquals("mementos don't match", memento, gottenMemento);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	void setDetectedLineDelimiter() throws IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			sDoc.setPreferredLineDelimiter("\n");
			String delim = sDoc.getPreferredLineDelimiter();
			assertEquals("set line delimiter failed", "\n", delim);

			sDoc.setPreferredLineDelimiter("\r\n");
			delim = sDoc.getPreferredLineDelimiter();
			assertEquals("set line delimiter failed", "\r\n", delim);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}

	public void testStringMatches() {
		// TODO: will need a test when this API is created
		// IStructuredModel model = getTestModel();
		// IStructuredDocument sDoc = model.getStructuredDocument();
	}

	public void testCreatePosition() throws BadPositionCategoryException, BadLocationException, IOException, CoreException {
		IStructuredModel model = getTestModel();
		try {
			IStructuredDocument sDoc = model.getStructuredDocument();
			Position p = new Position(0, 10);
			String[] categories = sDoc.getPositionCategories();
			for (int i = 0; i < categories.length; i++) {
				sDoc.addPosition(categories[i], p);
			}
			int found = 0;
			for (int i = 0; i < categories.length; i++) {
				Position[] positions = sDoc.getPositions(categories[i]);
				for (int j = 0; j < positions.length; j++) {
					if (positions[j] == p) {
						found++;
					}
				}
			}
			assertEquals("wrong number of positions", categories.length, found);
		}
		finally {
			if (model != null) {
				model.releaseFromEdit();
			}
		}
	}
}
