/*******************************************************************************
 * Copyright (c) 2002, 2013 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) 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:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial implementation
 * 	   IBM Corporation - additional tests
 *******************************************************************************/

package org.eclipse.ant.tests.ui.editor;

import java.util.List;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.IAntElement;
import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
import org.eclipse.jface.text.BadLocationException;

/**
 * Tests the correct creation of the outline for an xml file.
 * 
 */
public class AntEditorContentOutlineTests extends AbstractAntUITest {

	public AntEditorContentOutlineTests(String name) {
		super(name);
	}

	/**
	 * Tests the creation of the AntElementNode, that includes parsing a file and determining the correct location of the tags.
	 */
	public void testCreationOfOutlineTree() throws BadLocationException {
		AntModel model = getAntModel("buildtest1.xml"); //$NON-NLS-1$

		AntElementNode rootProject = model.getProjectNode();

		assertNotNull(rootProject);

		// Get the content as string
		String wholeDocumentString = getCurrentDocument().get();

		// <project>
		assertEquals(2, getStartingRow(rootProject));
		assertEquals(2, getStartingColumn(rootProject));
		int offset = wholeDocumentString.indexOf("project"); //$NON-NLS-1$
		assertEquals(offset, rootProject.getOffset());

		List<IAntElement> children = rootProject.getChildNodes();

		// <property name="propD">
		IAntElement element = children.get(0);
		assertEquals(3, getStartingRow(element));
		assertEquals(3, getStartingColumn(element)); // with tab in file
		assertEquals(3, getEndingRow(element));
		assertEquals(39, getEndingColumn(element)); // with tab in file

		offset = wholeDocumentString.indexOf("property"); //$NON-NLS-1$
		assertEquals(offset, element.getOffset());
		int length = "<property name=\"propD\" value=\"valD\" />".length(); //$NON-NLS-1$
		assertEquals(length - 1, element.getLength()); // we do not include the first '<'

		// <property file="buildtest1.properties">
		element = children.get(1);
		assertEquals(4, getStartingRow(element));
		assertEquals(6, getStartingColumn(element)); // no tab
		assertEquals(4, getEndingRow(element));
		assertEquals(45, getEndingColumn(element));

		// <property name="propV">
		element = children.get(2);
		assertEquals(5, getStartingRow(element));
		assertEquals(6, getStartingColumn(element));
		assertEquals(5, getEndingRow(element));
		assertEquals(42, getEndingColumn(element));

		// <target name="main">
		element = children.get(3);
		assertEquals(6, getStartingRow(element));
		assertEquals(6, getStartingColumn(element));
		assertEquals(9, getEndingRow(element));
		assertEquals(13, getEndingColumn(element));

		// <property name="property_in_target">
		element = element.getChildNodes().get(0);
		assertEquals(7, getStartingRow(element));
		assertEquals(10, getStartingColumn(element));
		assertEquals(7, getEndingRow(element));
		assertEquals(57, getEndingColumn(element));
		offset = wholeDocumentString.indexOf("property name=\"property_in_target\""); //$NON-NLS-1$
		assertEquals(offset, element.getOffset());

		assertEquals(21, getEndingRow(rootProject));
		assertEquals(10, getEndingColumn(rootProject));
	}

	private int getColumn(int offset, int line) throws BadLocationException {
		return offset - getCurrentDocument().getLineOffset(line - 1) + 1;
	}

	private int getStartingRow(IAntElement element) throws BadLocationException {
		return getCurrentDocument().getLineOfOffset(element.getOffset()) + 1;
	}

	private int getEndingRow(IAntElement element) throws BadLocationException {
		return getCurrentDocument().getLineOfOffset(element.getOffset() + element.getLength() - 1) + 1;
	}

	private int getStartingColumn(IAntElement element) throws BadLocationException {
		return getColumn(element.getOffset(), getStartingRow(element));
	}

	private int getEndingColumn(IAntElement element) throws BadLocationException {
		return getColumn(element.getOffset() + element.getLength() - 1, getEndingRow(element));
	}

	/**
	 * Tests the creation of the AntElementNode, that includes parsing a non-valid file.
	 */
	public void testParsingOfNonValidFile() throws BadLocationException {
		AntModel model = getAntModel("buildtest2.xml"); //$NON-NLS-1$

		IAntElement root = model.getProjectNode();
		assertNotNull(root);

		List<IAntElement> children = root.getChildNodes();

		// <target name="main">
		IAntElement element = children.get(2);
		assertEquals(5, getStartingRow(element));
		assertEquals(3, getStartingColumn(element)); // with tab in file
		assertEquals(5, getEndingRow(element));
		// main has no ending column as the element is not closed
		int offset = getCurrentDocument().get().indexOf("target name=\"main\""); //$NON-NLS-1$
		assertEquals(offset, element.getOffset());
	}

	/**
	 * Tests whether the outline can handle a build file with only the <project></project> tags.
	 */
	public void testWithProjectOnlyBuildFile() {
		AntModel model = getAntModel("projectOnly.xml"); //$NON-NLS-1$
		AntElementNode rootProject = model.getProjectNode();
		assertNotNull(rootProject);
	}

	/**
	 * Tests whether the outline can handle an empty build file.
	 */
	public void testWithEmptyBuildFile() {
		AntModel model = getAntModel("empty.xml"); //$NON-NLS-1$
		AntElementNode rootProject = model.getProjectNode();
		assertTrue(rootProject == null);
	}

	/**
	 * Some testing of getting the right location of tags.
	 */
	public void testAdvancedTaskLocation() throws BadLocationException {
		AntModel model = getAntModel("outline_select_test_build.xml"); //$NON-NLS-1$

		AntElementNode rootProject = model.getProjectNode();
		// Get the content as string
		String wholeDocumentString = getCurrentDocument().get();

		// <project>
		assertNotNull(rootProject);
		assertEquals(2, getStartingRow(rootProject));
		assertEquals(2, getStartingColumn(rootProject));
		int offset = wholeDocumentString.indexOf("project"); //$NON-NLS-1$

		assertEquals(offset, rootProject.getOffset());

		// <target name="properties">
		IAntElement element = rootProject.getChildNodes().get(1);
		assertNotNull(element);
		assertEquals("properties", element.getLabel()); //$NON-NLS-1$
		assertEquals(16, getStartingRow(element));
		assertEquals(3, getStartingColumn(element));
		offset = wholeDocumentString.indexOf("target name=\"properties\""); //$NON-NLS-1$

		assertEquals(offset, element.getOffset());
	}

	/**
	 * Tests if target is internal or not
	 */
	public void testInternalTargets() {
		AntModel model = getAntModel("internalTargets.xml"); //$NON-NLS-1$
		assertTrue("Target without description should be internal", model.getTargetNode("internal1").isInternal()); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Target with name starting with '-' should be internal", model.getTargetNode("-internal2").isInternal()); //$NON-NLS-1$ //$NON-NLS-2$
		assertFalse("Target with description attribute should not be internal", model.getTargetNode("non-internal").isInternal()); //$NON-NLS-1$ //$NON-NLS-2$
		assertFalse("Default target should not be internal", model.getTargetNode("-default").isInternal()); //$NON-NLS-1$ //$NON-NLS-2$
	}

	public static Test suite() {
		return new TestSuite(AntEditorContentOutlineTests.class);
	}
}