/*******************************************************************************
 * Copyright (c) 2002, 2015 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 API and implementation
 * 	   IBM Corporation - bug fixes
 *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49445
 *     Ericsson AB, Hamdan Msheik - Bug 389564
 *     Ericsson AB, Julian Enoch - Bug 389564
 *     David North - Bug 475839
 *******************************************************************************/

package org.eclipse.ant.internal.ui.model;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntImageDescriptor;
import org.eclipse.ant.internal.ui.AntUIImages;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IRegion;
import org.eclipse.swt.graphics.Image;

import com.ibm.icu.text.MessageFormat;

/**
 * General representation of an Ant buildfile element.
 * 
 */
public class AntElementNode implements IAdaptable, IAntElement {

	/**
	 * The offset of the corresponding source.
	 * 
	 * @see #getOffset()
	 */
	protected int fOffset = -1;

	/**
	 * The length of the corresponding source.
	 * 
	 * @see #getLength()
	 */
	protected int fLength = -1;

	/**
	 * The length of the source to select for this node
	 */
	protected int fSelectionLength;

	/**
	 * The parent node.
	 */
	protected AntElementNode fParent;

	/**
	 * The import node that "imported" this element
	 */
	private AntElementNode fImportNode;

	/**
	 * The child nodes.
	 */
	protected List<IAntElement> fChildNodes = null;

	/**
	 * The (tag-)name of the element.
	 */
	protected String fName;

	/**
	 * Whether this element has been generated as part of an element hierarchy this has problems. This is the severity of the problem.
	 * 
	 * @see XMLProblem#NO_PROBLEM
	 * @see XMLProblem#SEVERITY_ERROR
	 * @see XMLProblem#SEVERITY_WARNING
	 * @see XMLProblem#SEVERITY_FATAL_ERROR
	 */
	private int fProblemSeverity = AntModelProblem.NO_PROBLEM;

	private String fProblemMessage = null;

	/**
	 * The absolute file system path of the file this element is defined within.
	 */
	private String fFilePath;

	/**
	 * Whether this element has been generated from an external entity definition
	 */
	private boolean fIsExternal = false;

	/**
	 * The unique (in the corresponding element tree) path of this element.
	 */
	private String fElementPath;

	/**
	 * The (not necessarily unique) identifier of this element.
	 */
	private String fElementIdentifier;

	/**
	 * The problem associated with this node. May be <code>null</code>.
	 */
	private IProblem fProblem;

	/**
	 * The unique index of this element in it's parents child collection
	 */
	private int fIndex = 0;

	/**
	 * Only used when opening an import element to indicate the location in the imported file
	 */
	private int fLine;
	private int fColumn;

	/**
	 * Creates an instance with the specified name.
	 */
	public AntElementNode(String aName) {
		fName = aName;
	}

	public AntElementNode() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getName()
	 */
	@Override
	public String getName() {
		return fName;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getLabel()
	 */
	@Override
	public String getLabel() {
		return getName();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getChildNodes()
	 */
	@Override
	public List<IAntElement> getChildNodes() {
		return fChildNodes;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getParentNode()
	 */
	@Override
	public IAntElement getParentNode() {
		return fParent;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getProjectNode()
	 */
	@Override
	public AntProjectNode getProjectNode() {
		IAntElement projectParent = getParentNode();
		while (projectParent != null && !(projectParent instanceof AntProjectNode)) {
			projectParent = projectParent.getParentNode();
		}
		return (AntProjectNode) projectParent;
	}

	/**
	 * Adds the specified element as a child.
	 * <P>
	 * The specified element will have this assigned as its parent.
	 */
	public void addChildNode(AntElementNode childElement) {
		childElement.setParent(this);
		synchronized (this) {
			if (fChildNodes == null) {
				fChildNodes = new ArrayList<IAntElement>();
			}
			fChildNodes.add(childElement);
			childElement.setIndex(fChildNodes.size() - 1);
		}
	}

	private void setIndex(int index) {
		fIndex = index;
	}

	protected void setParent(AntElementNode node) {
		fParent = node;
	}

	/**
	 * Sets the absolute file system path of the file this element is defined within.
	 */
	public void setFilePath(String path) {
		if (path == null) {
			return;
		}
		URL url = null;
		try {
			url = new URL(path);
		}
		catch (MalformedURLException e) {
			fFilePath = path;
			return;
		}

		try {
			URL fileURL = FileLocator.toFileURL(url);
			// Bug 475839 - This is a quick fix for regression in 4.5.1, needs to be worked on in 4.6 via 476266
			if (IAntCoreConstants.FILE.equals(fileURL.getProtocol())) {
				fFilePath = new Path((URIUtil.toFile(URIUtil.toURI(fileURL))).getAbsolutePath()).toString();
			}
		}
		catch (URISyntaxException e) {
			AntUIPlugin.log(e);
		}
		catch (IOException e) {
			AntUIPlugin.log(e);
		}
	}

	/**
	 * Returns the absolute file system path of the file this element is defined within. Only relevant for nodes that are external
	 * 
	 * @see #isExternal()
	 */
	public String getFilePath() {
		return fFilePath;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getOffset()
	 */
	@Override
	public int getOffset() {
		return fOffset;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#setOffset(int)
	 */
	@Override
	public void setOffset(int anOffset) {
		fOffset = anOffset;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getLength()
	 */
	@Override
	public int getLength() {
		return fLength;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#setLength(int)
	 */
	@Override
	public void setLength(int aLength) {
		fLength = aLength;
		if (fProblem != null && fProblem instanceof AntModelProblem) {
			((AntModelProblem) fProblem).setLength(aLength);
		}
	}

	/**
	 * Returns a string representation of this element.
	 */
	@Override
	public String toString() {
		return "Ant Element Node: " + getLabel() + " Offset: " + getOffset() + " Length: " + getLength(); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#isErrorNode()
	 */
	@Override
	public boolean isErrorNode() {
		return fProblemSeverity == AntModelProblem.SEVERITY_ERROR || fProblemSeverity == AntModelProblem.SEVERITY_FATAL_ERROR;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#isWarningNode()
	 */
	@Override
	public boolean isWarningNode() {
		return fProblemSeverity == AntModelProblem.SEVERITY_WARNING;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#setProblemSeverity(int)
	 */
	@Override
	public void setProblemSeverity(int severity) {
		fProblemSeverity = severity;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#isExternal()
	 */
	@Override
	public boolean isExternal() {
		return fIsExternal;
	}

	/**
	 * Sets whether this xml element is defined in an external entity.
	 */
	public void setExternal(boolean isExternal) {
		fIsExternal = isExternal;
	}

	/**
	 * Returns a unique string representation of this element. The format of the string is not specified.
	 * 
	 * @return the string representation
	 */
	@Override
	public String getElementPath() {
		if (fElementPath == null) {
			StringBuffer buffer = new StringBuffer();
			String buildFileName = getProjectNode().getBuildFileName();
			if (buildFileName != null) {
				buffer.append(buildFileName);
			}
			buffer.append(getParentNode() != null ? getParentNode().getElementPath() : IAntCoreConstants.EMPTY_STRING);
			buffer.append('/');
			buffer.append(getElementIdentifier());
			buffer.append('[');
			buffer.append(fIndex);
			buffer.append(']');

			fElementPath = buffer.toString();
		}
		return fElementPath;
	}

	private String getElementIdentifier() {
		if (fElementIdentifier == null) {
			StringBuffer buffer = escape(new StringBuffer(getName() != null ? getName() : IAntCoreConstants.EMPTY_STRING), '\\', "$/[]\\"); //$NON-NLS-1$
			buffer.append('$');
			buffer.append(escape(new StringBuffer(getLabel() != null ? getLabel() : IAntCoreConstants.EMPTY_STRING), '\\', "$/[]\\").toString()); //$NON-NLS-1$

			fElementIdentifier = buffer.toString();
		}
		return fElementIdentifier;
	}

	private StringBuffer escape(StringBuffer sb, char esc, String special) {
		for (int i = 0; i < sb.length(); i++) {
			if (special.indexOf(sb.charAt(i)) >= 0) {
				sb.insert(i++, esc);
			}
		}

		return sb;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object o2) {
		Object o1 = this;

		if (o1 == o2) {
			return true;
		}
		if (o2 == null) {
			return false;
		}
		if (!(o1 instanceof AntElementNode || o2 instanceof AntElementNode)) {
			return o2.equals(o1);
		}
		if (!(o1 instanceof AntElementNode && o2 instanceof AntElementNode)) {
			return false;
		}

		AntElementNode e1 = (AntElementNode) o1;
		AntElementNode e2 = (AntElementNode) o2;

		return e1.getElementPath().equals(e2.getElementPath());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return getElementPath().hashCode();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getSelectionLength()
	 */
	@Override
	public int getSelectionLength() {
		return fSelectionLength;
	}

	public void setSelectionLength(int selectionLength) {
		this.fSelectionLength = selectionLength;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getNode(int)
	 */
	@Override
	public AntElementNode getNode(int sourceOffset) {
		synchronized (this) {
			if (fChildNodes != null) {
				for (IAntElement node : fChildNodes) {
					AntElementNode containingNode = node.getNode(sourceOffset);
					if (containingNode != null) {
						return containingNode;
					}
				}
			}
		}
		if (fLength == -1 && fOffset <= sourceOffset && !isExternal()) { // this is still an open element
			return this;
		}
		if (fOffset <= sourceOffset && sourceOffset <= (fOffset + fLength - 2)) {
			return this;
		}

		return null;
	}

	public Image getImage() {
		int flags = 0;

		if (isErrorNode()) {
			flags = flags | AntImageDescriptor.HAS_ERRORS;
		} else if (isWarningNode()) {
			flags = flags | AntImageDescriptor.HAS_WARNINGS;
		}
		if (fImportNode != null || isExternal()) {
			flags = flags | AntImageDescriptor.IMPORTED;
		}
		ImageDescriptor base = getBaseImageDescriptor();
		return AntUIImages.getImage(new AntImageDescriptor(base, flags));
	}

	protected ImageDescriptor getBaseImageDescriptor() {
		return AntUIImages.getImageDescriptor(IAntUIConstants.IMG_TASK_PROPOSAL);
	}

	protected IAntModel getAntModel() {
		IAntElement parentNode = getParentNode();
		while (!(parentNode instanceof AntProjectNode)) {
			parentNode = parentNode.getParentNode();
		}
		if (parentNode instanceof AntProjectNode) {
			return ((AntProjectNode) parentNode).getAntModel();
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#setProblem(org.eclipse.ant.internal.ui.model.IProblem)
	 */
	@Override
	public void setProblem(IProblem problem) {
		fProblem = problem;
	}

	/**
	 * @return
	 */
	public IProblem getProblem() {
		return fProblem;
	}

	protected void appendEntityName(StringBuffer displayName) {
		String path = getFilePath();

		if (getImportNode() != null) {
			displayName.append(MessageFormat.format(AntModelMessages.AntElementNode_9, new Object[] { getImportNode().getLabel() }));
		} else {
			String entityName = getAntModel().getEntityName(path);
			displayName.append(MessageFormat.format(AntModelMessages.AntElementNode_9, new Object[] { entityName }));
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getImportNode()
	 */
	@Override
	public AntElementNode getImportNode() {
		return fImportNode;
	}

	public void setImportNode(AntElementNode importNode) {
		fImportNode = importNode;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#hasChildren()
	 */
	@Override
	public boolean hasChildren() {
		if (fChildNodes == null) {
			return false;
		}
		return !fChildNodes.isEmpty();
	}

	public void reset() {
		fChildNodes = null;
	}

	public void setExternalInfo(int line, int column) {
		fLine = line;
		fColumn = column;
	}

	public int[] getExternalInfo() {
		return new int[] { fLine, fColumn };
	}

	/**
	 * Return the resource that contains the definition of this Ant node.
	 * 
	 * @return The resource that contains the definition of this ant node or <code>null</code> if that resource could not be determined (a buildfile
	 *         that is external to the workspace).
	 */
	public IFile getIFile() {
		if (isExternal()) {
			return AntUtil.getFileForLocation(fFilePath, null);
		}
		return getBuildFileResource();
	}

	/**
	 * Return the resource that is the main build file for this Ant node.
	 * 
	 * @return The resource that is the main buildfile for this ant node or <code>null</code> if that resource could not be determined (a buildfile
	 *         that is external to the workspace).
	 */
	public IFile getBuildFileResource() {
		LocationProvider locationProvider = getAntModel().getLocationProvider();
		return locationProvider.getFile();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}

	/**
	 * Returns whether this node is a structural node that should be shown in the buildfile outline. For example, an AntCommentNode would return
	 * <code>false</code>
	 * 
	 * @return whether this node is a structural node that should be shown in the buildfile outline
	 */
	public boolean isStructuralNode() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#collapseProjection()
	 */
	@Override
	public boolean collapseProjection() {
		return false;
	}

	public void dispose() {
		getAntModel().dispose();
	}

	/**
	 * Returns the name or path of the element referenced at the offset within the declaration of this node or <code>null</code> if no element is
	 * referenced at the offset
	 * 
	 * @param offset
	 *            The offset within the declaration of this node
	 * @return <code>null</code> or the name or path of the referenced element
	 */
	public String getReferencedElement(int offset) {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#getProblemMessage()
	 */
	@Override
	public String getProblemMessage() {
		return fProblemMessage;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#setProblemMessage(java.lang.String)
	 */
	@Override
	public void setProblemMessage(String problemMessage) {
		fProblemMessage = problemMessage;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#containsOccurrence(java.lang.String)
	 */
	@Override
	public boolean containsOccurrence(String identifier) {
		return false;
	}

	/**
	 * Returns the identifier to use for matching occurrences in the Ant editor.
	 * 
	 * @return the occurrences identifier for this node
	 */
	public String getOccurrencesIdentifier() {
		return getLabel();
	}

	/**
	 * Returns whether the supplied region can be considered as an area in this node containing a reference.
	 * 
	 * @param region
	 *            the area to consider for finding a reference
	 * @return whether a reference could exist in this node from the supplied region
	 */
	public boolean isRegionPotentialReference(IRegion region) {
		return region.getOffset() >= fOffset;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.IAntElement#computeIdentifierOffsets(java.lang.String)
	 */
	@Override
	public List<Integer> computeIdentifierOffsets(String identifier) {
		return null;
	}

	/**
	 * Returns whether the supplied region is from within this node's declaration identifier area
	 * 
	 * @param region
	 *            The region to check
	 * @return whether the region is from within this node and is the declaration of a reference.
	 */
	public boolean isFromDeclaration(IRegion region) {
		return false;
	}

	protected boolean checkReferenceRegion(IRegion region, String textToSearch, String attributeName) {
		int attributeOffset = textToSearch.indexOf(attributeName);
		while (attributeOffset > 0 && !Character.isWhitespace(textToSearch.charAt(attributeOffset - 1))) {
			attributeOffset = textToSearch.indexOf(attributeName, attributeOffset + 1);
		}
		if (attributeOffset != -1) {
			attributeOffset += attributeName.length();
			int attributeOffsetEnd = textToSearch.indexOf('"', attributeOffset);
			attributeOffsetEnd = textToSearch.indexOf('"', attributeOffsetEnd + 1);
			return region.getOffset() >= getOffset() + attributeOffset
					&& (region.getOffset() + region.getLength()) <= getOffset() + attributeOffsetEnd;
		}
		return false;
	}
}
