/*******************************************************************************
 * 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<>();
		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;
	}
}
