/*=============================================================================#
 # Copyright (c) 2010, 2021 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 java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.internal.ltk.buildpath.core.Messages;


public abstract class BuildpathInitializer {
	
	
	/**
	 * Status code indicating that an attribute is not supported.
	 */
	public static final int NOT_SUPPORTED= 1 << 16;
	
	/**
	 * Status code indicating that an attribute is not modifiable.
	 */
	public static final int READ_ONLY= 1 << 17;
	
	
	/**
	 * Status constant indicating that a buildpath entry was invalid
	 */
	public static final int INVALID_BUILDPATH= 964;
	
	/**
	 * Status constant indicating that a naming collision would occur
	 * if the operation proceeded.
	 */
	public static final int NAME_COLLISION= 977;
	
	
	private static final IStatus VERIFIED_OK= new Status(IStatus.OK, LtkBuildpaths.BUNDLE_ID, 0, "OK", null); //$NON-NLS-1$
	
	
	public boolean canUpdateContainer(final IPath path, final IProject project) {
		return false;
	}
	
	public IStatus getAttributeStatus(final IPath path, final IProject project, final String key) {
		return null;
	}
	
	
	public IResource getWorkspaceTarget(final IPath path) {
		if (path == null || path.getDevice() != null) {
			return null;
		}
		final IWorkspace workspace= ResourcesPlugin.getWorkspace();
		if (workspace == null) {
			return null;
		}
		return workspace.getRoot().findMember(path);
	}
	
	protected String getEntryPathMsg(final IProject project, final IPath path) {
		return (project.getName().equals(path.segment(0))) ?
				path.removeFirstSegments(1).makeRelative().toString() :
				path.toString();
	}
	
	
	/**
	 * Validate a given buildpath and output location for a project, using the following rules:
	 * <ul>
	 *   <li>Buildpath entries cannot collide with each other; that is, all entry paths must be unique.
	 *   <li>The project output location path cannot be null, must be absolute and located inside the project.
	 *   <li>Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
	 *   <li>A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
	 *   <li>Buildpath entries or output locations cannot coincidate or be nested in each other, except for the following scenario listed below:
	 *     <ul><li>A source folder can coincidate with its own output location, in which case this output can then contain library archives.
	 *         However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it. </li>
	 *         <li>A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
	 *         <li>An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output
	 *             location is excluded from the source folder. </li>
	 *    </ul>
	 * </ul>
	 * 
	 * Note that the buildpath entries are not validated automatically. Only bound variables or containers are considered
	 * in the checking process (this allows to perform a consistency check on a buildpath which has references to
	 * yet non existing projects, folders, ...).
	 * <p>
	 * This validation is intended to anticipate buildpath issues prior to assigning it to a project. In particular, it will automatically
	 * be performed during the buildpath setting operation (if validation fails, the buildpath setting will not complete).
	 * <p>
	 * 
	 * @param project the given java project
	 * @param rawBuildpath a given buildpath
	 * @param projectOutputLocation a given output location
	 * @return a status object with code <code>IStatus.OK</code> if
	 *     the given buildpath and output location are compatible, otherwise a status
	 *     object indicating what is wrong with the buildpath or output location
	 */
	public IStatus validateBuildpath(final IProject project, final List<BuildpathElement> rawBuildpath) {
		// tolerate null path, it will be reset to default
		if (rawBuildpath == null) {
			return VERIFIED_OK;
		}
		
		// check duplicate entries on raw buildpath only
		{	final Set<IPath> pathes= new HashSet<>(rawBuildpath.size());
			for (final BuildpathElement element : rawBuildpath) {
				final IPath path= element.getPath();
				if (!pathes.add(path)){
					return createErrorStatus(NAME_COLLISION, NLS.bind(
							Messages.BuildpathStatus_DuplicateEntryPath_message,
							getEntryPathMsg(project, path), project.getName() ));
				}
			}
		}
		
		for (final BuildpathElement element : rawBuildpath) {
			final IStatus status= validateBuildpathEntry(project, element);
			if (status.getSeverity() == IStatus.ERROR) {
				return status;
			}
		}
		
		return VERIFIED_OK;
	}
	
	protected IStatus validateBuildpathEntry(final IProject project, final BuildpathElement entry) {
		final IPath path= entry.getPath();
		
		// Build some common strings for status message
		final String projectName= project.getName();
		
		switch (entry.getTypeName()) {
		case BuildpathElement.SOURCE:
			if (!path.isAbsolute() || path.isEmpty()) {
				return createErrorStatus(INVALID_BUILDPATH, NLS.bind(
								Messages.BuildpathStatus_Entry_IllegalSourceFolderPath_message,
								getEntryPathMsg(project, path), projectName ));
			}
			{	final IPath projectPath= project.getProject().getFullPath();
				if (!projectPath.isPrefixOf(path) || getWorkspaceTarget(path) == null) {
					return createErrorStatus(INVALID_BUILDPATH, NLS.bind(
							Messages.BuildpathStatus_Entry_UnboundSourceFolder_message,
							getEntryPathMsg(project, path), projectName ));
				}
			}
			break;
		}
		
		// Validate extra attributes
		final ImList<BuildpathAttribute> extraAttributes= entry.getExtraAttributes();
		if (extraAttributes != null) {
			final int length= extraAttributes.size();
			final Set<String> set= new HashSet<>(length);
			for (final BuildpathAttribute attribute : extraAttributes) {
				if (!set.add(attribute.getName())) {
					return createErrorStatus(NAME_COLLISION, NLS.bind(
							Messages.BuildpathStatus_Entry_DuplicateExtraAttribute_message, new String[] {
									attribute.getName(),
									getEntryPathMsg(project, path),
									projectName
							}));
				}
			}
		}
		
		return VERIFIED_OK;
	}
	
	protected IStatus createErrorStatus(final int code, final String message) {
		return new Status(IStatus.ERROR, LtkBuildpaths.BUNDLE_ID, code, message, null);
	}
	
}
