/*=============================================================================#
 # Copyright (c) 2000, 2020 IBM Corporation and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     IBM Corporation - org.eclipse.jdt: initial API and implementation
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.buildpaths.core;

import java.util.Objects;

import org.eclipse.core.runtime.IPath;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.ObjectUtils;


public class BuildpathElement implements IBuildpathElement {
	
	
	private static final ImList<String> UNINITIALIZED_PATTERNS= ImCollections.newList("UNINITIALIZED_PATTERNS"); //$NON-NLS-1$
	
	
	private final BuildpathElementType type;
	
	/**
	 * The meaning of the path of a classpath entry depends on its entry kind:<ul>
	 *  <li>Source code in the current project (<code>SOURCE</code>) -
	 *     The path associated with this entry is the absolute path to the root folder. </li>
	 *  <li>A binary library in the current project (<code>LIBRARY</code>) - the path
	 *     associated with this entry is the absolute path to the JAR (or root folder), and
	 *     in case it refers to an external JAR, then there is no associated resource in
	 *     the workbench.
	 *  <li>A required project (<code>PROJECT</code>) - the path of the entry denotes the
	 *     path to the corresponding project resource.</li>
	 *  <li>A variable entry (<code>VARIABLE</code>) - the first segment of the path
	 *      is the name of a classpath variable. If this classpath variable
	 *     is bound to the path <it>P</it>, the path of the corresponding classpath entry
	 *     is computed by appending to <it>P</it> the segments of the returned
	 *     path without the variable.</li>
	 *   <li> A container entry (<code>CONTAINER</code>) - the first segment of the path is denoting
	 *     the unique container identifier (for which a <code>ClasspathContainerInitializer</code> could be
	 *     registered), and the remaining segments are used as additional hints for resolving the container entry to
	 *     an actual <code>IClasspathContainer</code>.</li>
	 */
	private final IPath path;
	
	/**
	 * Patterns allowing to include/exclude portions of the resource tree denoted by this entry path.
	 */
	private final ImList<IPath> inclusionPatterns;
	private volatile ImList<String> fullInclusionPatterns;
	private final ImList<IPath> exclusionPatterns;
	private volatile ImList<String> fullExclusionPatterns;
	
	
	/**
	 * Describes the path to the source archive associated with this
	 * classpath entry, or <code>null</code> if this classpath entry has no
	 * source attachment.
	 * <p>
	 * Only library and variable classpath entries may have source attachments.
	 * For library classpath entries, the result path (if present) locates a source
	 * archive. For variable classpath entries, the result path (if present) has
	 * an analogous form and meaning as the variable path, namely the first segment
	 * is the name of a classpath variable.
	 */
	private final IPath sourceAttachmentPath;
	
	/**
	 * Describes the path within the source archive where package fragments
	 * are located. An empty path indicates that packages are located at
	 * the root of the source archive. Returns a non-<code>null</code> value
	 * if and only if <code>getSourceAttachmentPath</code> returns
	 * a non-<code>null</code> value.
	 */
	private final IPath sourceAttachmentRootPath;
	
	/**
	 * See {@link IBuildpathElement#getReferencingEntry()}
	 */
	private final IBuildpathElement referencingElement;
	
	/**
	 * Specific output location (for this source entry)
	 */
	private final IPath specificOutputPath;
	
	/**
	 * The export flag
	 */
	private final boolean isExported;
	
	/**
	 * The extra attributes
	 */
	private final ImList<IBuildpathAttribute> extraAttributes;
	
	
	/**
	 * Creates a class path entry of the specified kind with the given path.
	 */
	public BuildpathElement(final BuildpathElementType type,
			final IPath path, final ImList<IPath> inclusionPatterns, final ImList<IPath> exclusionPatterns,
			final IPath sourceAttachmentPath, final IPath sourceAttachmentRootPath,
			final IPath specificOutputLocation,
			final IBuildpathElement referencingEntry,
			final boolean isExported,
			final ImList<IBuildpathAttribute> extraAttributes) {
		if (type == null) {
			throw new NullPointerException("type"); //$NON-NLS-1$
		}
		if (path == null) {
			throw new NullPointerException("path"); //$NON-NLS-1$
		}
		
		this.type= type;
		this.path= path;
		this.inclusionPatterns= inclusionPatterns;
		this.exclusionPatterns= exclusionPatterns;
		this.referencingElement= referencingEntry;
		
		if (this.inclusionPatterns != null && !this.inclusionPatterns.isEmpty()) {
			this.fullInclusionPatterns= UNINITIALIZED_PATTERNS;
		}
		if (this.exclusionPatterns != null && !this.exclusionPatterns.isEmpty()) {
			this.fullExclusionPatterns= UNINITIALIZED_PATTERNS;
		}
		
		this.sourceAttachmentPath= sourceAttachmentPath;
		this.sourceAttachmentRootPath= sourceAttachmentRootPath;
		this.specificOutputPath= specificOutputLocation;
		
		this.isExported= isExported;
		
		this.extraAttributes= (extraAttributes != null) ? extraAttributes : ImCollections.<IBuildpathAttribute>emptyList();
	}
	
	
	@Override
	public final BuildpathElementType getType() {
		return this.type;
	}
	
	@Override
	public final String getTypeName() {
		return this.type.getName();
	}
	
	@Override
	public final IPath getPath() {
		return this.path;
	}
	
	@Override
	public final ImList<IPath> getInclusionPatterns() {
		return this.inclusionPatterns;
	}
	
	@Override
	public final ImList<IPath> getExclusionPatterns() {
		return this.exclusionPatterns;
	}
	
	private ImList<String> createFullPatterns(final ImList<IPath> patterns) {
		final int length= patterns.size();
		final String[] fullPatterns= new String[length];
		final IPath prefixPath= this.path.removeTrailingSeparator();
		for (int i= 0; i < length; i++) {
			fullPatterns[i]= prefixPath.append(patterns.get(i)).toString();
		}
		return ImCollections.newList(fullPatterns);
	}
	
	public ImList<String> getFullInclusionPatterns() {
		ImList<String> patterns= this.fullInclusionPatterns;
		if (patterns == UNINITIALIZED_PATTERNS) {
			patterns= this.fullInclusionPatterns= createFullPatterns(this.inclusionPatterns);
		}
		return patterns;
	}
	
	public ImList<String> getFullExclusionPatterns() {
		ImList<String> patterns= this.fullExclusionPatterns;
		if (patterns == UNINITIALIZED_PATTERNS) {
			patterns= this.fullExclusionPatterns= createFullPatterns(this.exclusionPatterns);
		}
		return patterns;
	}
	
	@Override
	public IPath getOutputPath() {
		return this.specificOutputPath;
	}
	
	
	@Override
	public ImList<IBuildpathAttribute> getExtraAttributes() {
		return this.extraAttributes;
	}
	
	public IBuildpathAttribute getAttribute(final String name) {
		for (final IBuildpathAttribute attribute : this.extraAttributes) {
			if (attribute.getName().equals(name)) {
				return attribute;
			}
		}
		return null;
	}
	
	
	@Override
	public IPath getSourceAttachmentPath() {
		return this.sourceAttachmentPath;
	}
	
	public IPath getSourceAttachmentRootPath() {
		return this.sourceAttachmentRootPath;
	}
	
	public IBuildpathElement getReferencingEntry() {
		return this.referencingElement;
	}
	
	@Override
	public boolean isExported() {
		return this.isExported;
	}
	
	
	@Override
	public int hashCode() {
		return this.type.hashCode() ^ this.path.hashCode();
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof BuildpathElement) {
			final BuildpathElement other= (BuildpathElement) obj;
			return (this.type == other.type
					&& this.isExported == other.isExported()
					&& this.path.equals(other.getPath())
					&& Objects.equals(this.sourceAttachmentPath, other.sourceAttachmentPath)
					&& Objects.equals(getSourceAttachmentRootPath(), other.sourceAttachmentRootPath)
					&& BuildpathsUtils.equalPatterns(this.inclusionPatterns, other.getInclusionPatterns())
					&& BuildpathsUtils.equalPatterns(this.exclusionPatterns, other.getExclusionPatterns())
					&& Objects.equals(this.specificOutputPath, other.specificOutputPath)
					&& this.extraAttributes.equals(other.extraAttributes) );
		}
		return false;
	}
	
	@Override
	public String toString() {
		final ObjectUtils.ToStringBuilder sb= new ObjectUtils.ToStringBuilder("BuildpathElement"); //$NON-NLS-1$
		sb.append(" ["); //$NON-NLS-1$
		sb.append(this.type.getName());
		sb.append("]:"); //$NON-NLS-1$
		sb.append(getPath().toString());
		sb.addProp("including", getInclusionPatterns()); //$NON-NLS-1$
		sb.addProp("excluding", getExclusionPatterns()); //$NON-NLS-1$
		if (getSourceAttachmentPath() != null) {
			sb.addProp("sourcePath", getSourceAttachmentPath().toString()); //$NON-NLS-1$
			if (getSourceAttachmentRootPath() != null) {
				sb.append(':');
				sb.append(getSourceAttachmentRootPath().toString());
			}
		}
		if (getOutputPath() != null) {
			sb.addProp("outputPath", getOutputPath()); //$NON-NLS-1$
		}
		sb.addProp("isExported", this.isExported);
		final ImList<IBuildpathAttribute> attributes= getExtraAttributes();
		if (!attributes.isEmpty()) {
			sb.addProp("extraAttributes", attributes); //$NON-NLS-1$
		}
		return sb.toString();
	}
	
}
