/*******************************************************************************
 * Copyright (c) 2004, 2013 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.ant.internal.ui.model;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import org.apache.tools.ant.ExtensionPoint;
import org.apache.tools.ant.Target;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIImages;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IRegion;

public class AntTargetNode extends AntElementNode {

	private Target fTarget = null;
	private String fLabel = null;
	private boolean isExtension = false;

	// use newAntTargetNode() instead
	private AntTargetNode(Target target) {
		super("target"); //$NON-NLS-1$
		fTarget = target;
	}

	// use newAntTargetNode() instead
	private AntTargetNode(ExtensionPoint target) {
		super("extension-point"); //$NON-NLS-1$
		fTarget = target;
		isExtension = true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getLabel()
	 */
	@Override
	public String getLabel() {
		if (fLabel == null) {
			StringBuffer displayName = new StringBuffer(getTargetName());
			if (isDefaultTarget()) {
				displayName.append(AntModelMessages.AntTargetNode_2);
			}
			if (isExternal()) {
				appendEntityName(displayName);
			}

			fLabel = displayName.toString();
		}
		return fLabel;
	}

	public Target getTarget() {
		return fTarget;
	}

	public boolean isDefaultTarget() {
		String targetName = fTarget.getName();
		if (targetName == null) {
			return false;
		}
		return targetName.equals(fTarget.getProject().getDefaultTarget());
	}

	/**
	 * Returns whether this target is an internal target. Internal targets are targets which has no description or starts with hyphen ('-') character.
	 * The default target is never considered internal.
	 * 
	 * @return whether the given target is an internal target
	 */
	public boolean isInternal() {
		Target target = getTarget();
		return (target.getDescription() == null || getTargetName().startsWith("-")) && !isDefaultTarget(); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.editor.model.AntElementNode#getBaseImageDescriptor()
	 */
	@Override
	protected ImageDescriptor getBaseImageDescriptor() {
		ImageDescriptor base = null;
		if (isDefaultTarget()) {
			base = AntUIImages.getImageDescriptor(IAntUIConstants.IMG_ANT_DEFAULT_TARGET);
		} else if (isInternal()) {
			base = AntUIImages.getImageDescriptor(IAntUIConstants.IMG_ANT_TARGET_INTERNAL);
		} else {
			base = AntUIImages.getImageDescriptor(IAntUIConstants.IMG_ANT_TARGET);
		}
		return base;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.editor.model.AntElementNode#reset()
	 */
	@Override
	public void reset() {
		super.reset();
		Map<String, Target> currentTargets = fTarget.getProject().getTargets();
		if (currentTargets.get(fTarget.getName()) != null) {
			currentTargets.remove(fTarget.getName());
		}
	}

	/**
	 * Returns the name of a missing dependency or <code>null</code> if all dependencies exist in the project.
	 */
	public String checkDependencies() {
		Enumeration<String> dependencies = fTarget.getDependencies();
		while (dependencies.hasMoreElements()) {
			String dependency = dependencies.nextElement();
			if (fTarget.getProject().getTargets().get(dependency) == null) {
				return dependency;
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#collapseProjection()
	 */
	@Override
	public boolean collapseProjection() {
		IPreferenceStore store = AntUIPlugin.getDefault().getPreferenceStore();
		if (store.getBoolean(AntEditorPreferenceConstants.EDITOR_FOLDING_TARGETS)) {
			return true;
		}
		return false;
	}

	public String getTargetName() {
		String targetName = fTarget.getName();
		if (targetName == null) {
			targetName = "target"; //$NON-NLS-1$
			setProblemSeverity(AntModelProblem.SEVERITY_ERROR);
		}
		return targetName;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#containsOccurrence(java.lang.String)
	 */
	@Override
	public boolean containsOccurrence(String identifier) {
		if (getTargetName().equals(identifier)) {
			return true;
		}
		Enumeration<String> dependencies = fTarget.getDependencies();
		while (dependencies.hasMoreElements()) {
			String dependency = dependencies.nextElement();
			if (dependency.equals(identifier)) {
				return true;
			}
		}
		// looking for properties
		if (identifier.startsWith("${") && identifier.endsWith("}")) { //$NON-NLS-1$ //$NON-NLS-2$
			String ifString = fTarget.getIf();
			if (ifString != null && ifString.endsWith(identifier.substring(2, identifier.length() - 1))) {
				return true;
			}
			String unlessString = fTarget.getUnless();
			if (unlessString != null && unlessString.endsWith(identifier.substring(2, identifier.length() - 1))) {
				return true;
			}
		}
		return false;
	}

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

	@Override
	public List<Integer> computeIdentifierOffsets(String identifier) {
		String textToSearch = getAntModel().getText(getOffset(), getLength());
		if (textToSearch == null || textToSearch.length() == 0 || identifier.length() == 0) {
			return null;
		}
		List<Integer> results = new ArrayList<Integer>();
		if (getTargetName().equals(identifier)) {
			int nameOffset = textToSearch.indexOf(IAntCoreConstants.NAME);
			nameOffset = textToSearch.indexOf(identifier, nameOffset);
			results.add(new Integer(getOffset() + nameOffset));
		} else {
			String ifString = fTarget.getIf();
			if (ifString != null && ifString.endsWith(identifier)) {
				int ifOffset = textToSearch.indexOf("if"); //$NON-NLS-1$
				ifOffset = textToSearch.indexOf(identifier, ifOffset);
				results.add(new Integer(getOffset() + ifOffset));
			} else {
				String unlessString = fTarget.getUnless();
				if (unlessString != null && unlessString.endsWith(identifier)) {
					int unlessOffset = textToSearch.indexOf("unless"); //$NON-NLS-1$
					unlessOffset = textToSearch.indexOf(identifier, unlessOffset);
					results.add(new Integer(getOffset() + unlessOffset));
				} else {
					int dependsOffset = textToSearch.indexOf("depends"); //$NON-NLS-1$
					while (dependsOffset > 0 && !Character.isWhitespace(textToSearch.charAt(dependsOffset - 1))) {
						dependsOffset = textToSearch.indexOf("depends", dependsOffset + 1); //$NON-NLS-1$
					}
					if (dependsOffset != -1) {
						dependsOffset += 7;
						int dependsOffsetEnd = textToSearch.indexOf('"', dependsOffset);
						dependsOffsetEnd = textToSearch.indexOf('"', dependsOffsetEnd + 1);
						while (dependsOffset < dependsOffsetEnd) {
							dependsOffset = textToSearch.indexOf(identifier, dependsOffset);
							if (dependsOffset == -1 || dependsOffset > dependsOffsetEnd) {
								break;
							}
							char delimiter = textToSearch.charAt(dependsOffset - 1);
							if (delimiter == ',' || delimiter == '"' || delimiter == ' ') {
								results.add(new Integer(getOffset() + dependsOffset));
							}
							dependsOffset += identifier.length();
						}
					}
				}
			}
		}
		return results;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#isRegionPotentialReference(org.eclipse.jface.text.IRegion)
	 */
	@Override
	public boolean isRegionPotentialReference(IRegion region) {
		boolean superOK = super.isRegionPotentialReference(region);
		if (!superOK) {
			return false;
		}

		String textToSearch = getAntModel().getText(getOffset(), getLength());
		if (textToSearch == null) {
			return false;
		}
		if (checkReferenceRegion(region, textToSearch, "depends")) { //$NON-NLS-1$
			return true;
		} else if (checkReferenceRegion(region, textToSearch, IAntCoreConstants.NAME)) {
			return true;
		} else if (checkReferenceRegion(region, textToSearch, "if")) { //$NON-NLS-1$
			return true;
		}
		return checkReferenceRegion(region, textToSearch, "unless"); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#isFromDeclaration(org.eclipse.jface.text.IRegion)
	 */
	@Override
	public boolean isFromDeclaration(IRegion region) {
		String textToSearch = getAntModel().getText(getOffset(), getLength());
		if (textToSearch == null || textToSearch.length() == 0) {
			return false;
		}
		return checkReferenceRegion(region, textToSearch, IAntCoreConstants.NAME);
	}

	/**
	 * @return if this node is an extension point
	 * 
	 */
	public boolean isExtensionPoint() {
		return isExtension;
	}

	/**
	 * This function should be used to construct the AntTargetNode
	 * 
	 * @param newTarget
	 * @return newly constructed AntTargetNode
	 * 
	 */
	public static AntTargetNode newAntTargetNode(Target newTarget) {
		AntTargetNode targetNode;
		if (newTarget instanceof ExtensionPoint) {
			targetNode = new AntTargetNode((ExtensionPoint) newTarget);
		} else {
			targetNode = new AntTargetNode(newTarget);
		}
		return targetNode;
	}
}
