/*=============================================================================#
 # 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.buildpath.core;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

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.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.ObjectUtils;


@NonNullByDefault
public class BasicBuildpathElement implements BuildpathElement {
	
	
	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 @Nullable ImList<IPath> inclusionPatterns;
	private volatile @Nullable ImList<String> fullInclusionPatterns;
	private final @Nullable ImList<IPath> exclusionPatterns;
	private volatile @Nullable 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 @Nullable 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 @Nullable IPath sourceAttachmentRootPath;
	
	/**
	 * See {@link BuildpathElement#getReferencingEntry()}
	 */
	private final @Nullable BuildpathElement referencingElement;
	
	/**
	 * Specific output location (for this source entry)
	 */
	private final @Nullable IPath specificOutputPath;
	
	/**
	 * The export flag
	 */
	private final boolean isExported;
	
	/**
	 * The extra attributes
	 */
	private final ImList<BuildpathAttribute> extraAttributes;
	
	
	/**
	 * Creates a class path entry of the specified kind with the given path.
	 */
	public BasicBuildpathElement(final BuildpathElementType type,
			final IPath path, final @Nullable ImList<IPath> inclusionPatterns, final @Nullable ImList<IPath> exclusionPatterns,
			final @Nullable IPath sourceAttachmentPath, final @Nullable IPath sourceAttachmentRootPath,
			final @Nullable IPath specificOutputLocation,
			final @Nullable BuildpathElement referencingEntry,
			final boolean isExported,
			final @Nullable ImList<BuildpathAttribute> extraAttributes) {
		this.type= nonNullAssert(type);
		this.path= nonNullAssert(path);
		this.inclusionPatterns= inclusionPatterns;
		this.fullInclusionPatterns= UNINITIALIZED_PATTERNS;
		this.exclusionPatterns= exclusionPatterns;
		this.fullExclusionPatterns= UNINITIALIZED_PATTERNS;
		this.referencingElement= referencingEntry;
		
		this.sourceAttachmentPath= sourceAttachmentPath;
		this.sourceAttachmentRootPath= sourceAttachmentRootPath;
		this.specificOutputPath= specificOutputLocation;
		
		this.isExported= isExported;
		
		this.extraAttributes= (extraAttributes != null) ? extraAttributes : ImCollections.<BuildpathAttribute>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 @Nullable ImList<IPath> getInclusionPatterns() {
		return this.inclusionPatterns;
	}
	
	@Override
	public final @Nullable ImList<IPath> getExclusionPatterns() {
		return this.exclusionPatterns;
	}
	
	private @Nullable ImList<String> createFullPatterns(final @Nullable ImList<IPath> patterns) {
		if (patterns == null || patterns.isEmpty()) {
			return null;
		}
		final int length= patterns.size();
		final String[] fullPatterns= new @NonNull 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 @Nullable ImList<String> getFullInclusionPatterns() {
		ImList<String> patterns= this.fullInclusionPatterns;
		if (patterns == UNINITIALIZED_PATTERNS) {
			patterns= this.fullInclusionPatterns= createFullPatterns(this.inclusionPatterns);
		}
		return patterns;
	}
	
	public @Nullable ImList<String> getFullExclusionPatterns() {
		ImList<String> patterns= this.fullExclusionPatterns;
		if (patterns == UNINITIALIZED_PATTERNS) {
			patterns= this.fullExclusionPatterns= createFullPatterns(this.exclusionPatterns);
		}
		return patterns;
	}
	
	@Override
	public @Nullable IPath getOutputPath() {
		return this.specificOutputPath;
	}
	
	
	@Override
	public ImList<BuildpathAttribute> getExtraAttributes() {
		return this.extraAttributes;
	}
	
	public @Nullable BuildpathAttribute getAttribute(final String name) {
		for (final BuildpathAttribute attribute : this.extraAttributes) {
			if (attribute.getName().equals(name)) {
				return attribute;
			}
		}
		return null;
	}
	
	
	@Override
	public @Nullable IPath getSourceAttachmentPath() {
		return this.sourceAttachmentPath;
	}
	
	public @Nullable IPath getSourceAttachmentRootPath() {
		return this.sourceAttachmentRootPath;
	}
	
	public @Nullable BuildpathElement 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 @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof BasicBuildpathElement) {
			final BasicBuildpathElement other= (BasicBuildpathElement)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)
					&& BuildpathUtils.equalPatterns(this.inclusionPatterns, other.getInclusionPatterns())
					&& BuildpathUtils.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("BasicBuildpathElement"); //$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$
		sb.addProp("sourcePath", getSourceAttachmentPath()); //$NON-NLS-1$
		{	final IPath rootPath= getSourceAttachmentRootPath();
			if (rootPath != null) {
				sb.append(':');
				sb.append(rootPath.toString());
			}
		}
		sb.addProp("outputPath", getOutputPath()); //$NON-NLS-1$
		sb.addProp("isExported", this.isExported);
		final ImList<BuildpathAttribute> attributes= getExtraAttributes();
		if (!attributes.isEmpty()) {
			sb.addProp("extraAttributes", attributes); //$NON-NLS-1$
		}
		return sb.toString();
	}
	
}
