/*******************************************************************************
 * Copyright (c) 2002, 2015 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) and others.
 *
 * This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * 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<>();
			}
			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);
			// To be worked in 4.6 via Bug 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) {
			StringBuilder buffer = new StringBuilder();
			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;
	}
}
