/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contributions for
 *								bug 186342 - [compiler][null] Using annotations for null checking
 *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
 *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.ArrayList;
import java.util.function.Predicate;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment;
import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
import org.eclipse.jdt.internal.compiler.util.HashtableOfType;

public class PackageBinding extends Binding implements TypeConstants {
	public long tagBits = 0; // See values in the interface TagBits below

	public char[][] compoundName;
	PackageBinding parent;
	ArrayList<SplitPackageBinding> wrappingSplitPackageBindings;
	public LookupEnvironment environment;
	/** Types in this map are either uniquely visible in the current module or ProblemReferenceBindings. */
	public HashtableOfType knownTypes;
	/** All visible member packages, i.e. observable packages associated with modules read by the current module. */
	HashtableOfPackage knownPackages;

	// code representing the default that has been defined for this package (using @NonNullByDefault)
	// one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT}
	private int defaultNullness = NO_NULL_DEFAULT;

	public ModuleBinding enclosingModule;

	/** Is this package exported from its module? NB: to query this property use {@link #isExported()} to ensure initialization. */
	Boolean isExported;

protected PackageBinding() {
	// for creating problem package
}
public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment, ModuleBinding enclosingModule) {
	this(new char[][] {topLevelPackageName}, null, environment, enclosingModule);
}
/* Create a normal package.
*/
public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment, ModuleBinding enclosingModule) {
	this.compoundName = compoundName;
	this.parent = parent;
	this.environment = environment;
	this.knownTypes = null; // initialized if used... class counts can be very large 300-600
	this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3
	
	if (compoundName != CharOperation.NO_CHAR_CHAR)
		checkIfNullAnnotationPackage();
	
	if (enclosingModule != null)
		this.enclosingModule = enclosingModule;
	else if (parent != null)
		this.enclosingModule = parent.enclosingModule; // stop-gap for any remaining calls that don't provide an enclosingModule (they should)
	
	if (this.enclosingModule == null)
		throw new IllegalStateException("Package should have an enclosing module"); //$NON-NLS-1$
}

public PackageBinding(LookupEnvironment environment) {
	this(CharOperation.NO_CHAR_CHAR, null, environment, environment.module);
}
protected void addNotFoundPackage(char[] simpleName) {
	this.knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage);
}
private void addNotFoundType(char[] simpleName) {
	if (this.knownTypes == null)
		this.knownTypes = new HashtableOfType(25);
	this.knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType);
}
/**
 * Remembers a sub-package.
 * For a split parent package this will include potentially enriching with siblings,
 * in which case the enriched (split) binding will be returned.
 */
PackageBinding addPackage(PackageBinding element, ModuleBinding module) {
	if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
	this.knownPackages.put(element.compoundName[element.compoundName.length - 1], element);
	return element;
}
void addType(ReferenceBinding element) {
	if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
	if (this.knownTypes == null)
		this.knownTypes = new HashtableOfType(25);
	char [] name = element.compoundName[element.compoundName.length - 1];
	ReferenceBinding priorType = this.knownTypes.getput(name, element);
	if (priorType != null && priorType.isUnresolvedType() && !element.isUnresolvedType()) {
		((UnresolvedReferenceBinding) priorType).setResolvedType(element, this.environment);
	}
	if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled)
		if (element.isAnnotationType() || element instanceof UnresolvedReferenceBinding) // unresolved types don't yet have the modifiers set
			checkIfNullAnnotationType(element);

	if (!element.isUnresolvedType() && this.wrappingSplitPackageBindings != null) {
		for (SplitPackageBinding splitPackageBinding : this.wrappingSplitPackageBindings) {
			if (splitPackageBinding.knownTypes != null) {
				ReferenceBinding prior = splitPackageBinding.knownTypes.get(name);
				if (prior != null && prior.isUnresolvedType() && !element.isUnresolvedType()) {
					((UnresolvedReferenceBinding) prior).setResolvedType(element, this.environment);
					splitPackageBinding.knownTypes.put(name, null); // forces re-checking for conflicts
				}
			}
		}
	}
}

ModuleBinding[] getDeclaringModules() {
	return new ModuleBinding[] { this.enclosingModule };
}

void clearMissingTagBit() {
	PackageBinding current = this;
	do {
		current.tagBits &= ~TagBits.HasMissingType;
	} while ((current = current.parent) != null);
}
/*
 * slash separated name
 * org.eclipse.jdt.core --> org/eclipse/jdt/core
 */
@Override
public char[] computeUniqueKey(boolean isLeaf) {
	return CharOperation.concatWith(this.compoundName, '/');
}
protected PackageBinding findPackage(char[] name, ModuleBinding module) {
	// delegate to the module to consider the module graph:
	return module.getPackage(this.compoundName, name);
}
/* Answer the subpackage named name; ask the oracle for the package if its not in the cache.
* Answer null if it could not be resolved.
*
* NOTE: This should only be used when we know there is NOT a type with the same name.
*/
PackageBinding getPackage(char[] name, ModuleBinding mod) {
	PackageBinding binding = getPackage0(name);
	if (binding != null) {
		if (binding == LookupEnvironment.TheNotFoundPackage)
			return null;
		else
			return binding;
	}
	if ((binding = findPackage(name, mod)) != null)
		return binding;

	// not found so remember a problem package binding in the cache for future lookups
	addNotFoundPackage(name);
	return null;
}
/** Answer the subpackage named name if it exists in the cache.
* Answer theNotFoundPackage if it could not be resolved the first time
* it was looked up, otherwise answer null.
* <p>
* NOTE: The returned package binding is guaranteed to be complete wrt. SplitPackageBinding,
* or, if no complete binding is yet available, we shyly answer null.
* </p><p>
* NOTE: Senders must convert theNotFoundPackage into a real problem
* package if its to returned.</p>
*/
PackageBinding getPackage0(char[] name) {
	return this.knownPackages.get(name);
}
/** Variant (see {@link #getPackage0(char[])}), that may even answer an incompletely
 *  combined package (in the case of SplitPackageBinding).
 */
PackageBinding getPackage0Any(char[] name) {
	return this.knownPackages.get(name);
}
/* Answer the type named name; ask the oracle for the type if its not in the cache.
* Answer a NotVisible problem type if the type is not visible from the invocationPackage.
* Answer null if it could not be resolved.
*
* NOTE: This should only be used by source types/scopes which know there is NOT a
* package with the same name.
*/

ReferenceBinding getType(char[] name, ModuleBinding mod) {
	ReferenceBinding referenceBinding = getType0(name);
	if (referenceBinding == null) {
		if ((referenceBinding = this.environment.askForType(this, name, mod)) == null) {
			// not found so remember a problem type binding in the cache for future lookups
			addNotFoundType(name);
			return null;
		}
	}

	if (referenceBinding == LookupEnvironment.TheNotFoundType)
		return null;

	referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this.environment, false /* no raw conversion for now */);
	if (referenceBinding.isNestedType())
		return new ProblemReferenceBinding(new char[][]{ name }, referenceBinding, ProblemReasons.InternalNameProvided);
	if (!mod.canAccess(this))
		return new ProblemReferenceBinding(referenceBinding.compoundName, referenceBinding, ProblemReasons.NotAccessible);
	// at this point we have only checked accessibility of the package, accessibility of the type will be checked by callers
	return referenceBinding;
}
/* Answer the type named name if it exists in the cache.
* Answer theNotFoundType if it could not be resolved the first time
* it was looked up, otherwise answer null.
*
* NOTE: Senders must convert theNotFoundType into a real problem
* reference type if its to returned.
*/

ReferenceBinding getType0(char[] name) {
	if (this.knownTypes == null)
		return null;
	return this.knownTypes.get(name);
}
/* Answer the package or type named name; ask the oracle if it is not in the cache.
* Answer null if it could not be resolved.
*
* When collisions exist between a type name & a package name, answer the type.
* Treat the package as if it does not exist... a problem was already reported when the type was defined.
*
* NOTE: no visibility checks are performed.
* THIS SHOULD ONLY BE USED BY SOURCE TYPES/SCOPES.
*/

public Binding getTypeOrPackage(char[] name, ModuleBinding mod, boolean splitPackageAllowed) {
	ReferenceBinding problemBinding = null;
	ReferenceBinding referenceBinding = getType0(name);
	lookForType0:
	if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
		referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this.environment, false /* no raw conversion for now */);
		if (referenceBinding.isNestedType()) {
			return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
		}
		boolean isSameModule = (this instanceof SplitPackageBinding) ? referenceBinding.module() == mod : this.enclosingModule == mod;
		if (!isSameModule && referenceBinding.isValidBinding() && !mod.canAccess(referenceBinding.fPackage)) {
			problemBinding = new ProblemReferenceBinding(referenceBinding.compoundName, referenceBinding, ProblemReasons.NotAccessible);
			break lookForType0;
		}
		if ((referenceBinding.tagBits & TagBits.HasMissingType) == 0) {
			return referenceBinding;
		}
		// referenceBinding is a MissingType, will return it if no package is found
	}

	PackageBinding packageBinding = getPackage0(name);
	if (packageBinding != null && packageBinding != LookupEnvironment.TheNotFoundPackage) {
		if (!splitPackageAllowed && packageBinding instanceof SplitPackageBinding) {
			return ((SplitPackageBinding) packageBinding).getVisibleFor(mod, false);
		}
		return packageBinding;
	}
	lookForType:
	if (referenceBinding == null && problemBinding == null) { // have not looked for it before
		if ((referenceBinding = this.environment.askForType(this, name, mod)) != null) {
			if (referenceBinding.isNestedType()) {
				return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
			}
			if (referenceBinding.isValidBinding() && !mod.canAccess(referenceBinding.fPackage)) {
				problemBinding = new ProblemReferenceBinding(referenceBinding.compoundName, referenceBinding, ProblemReasons.NotAccessible);
				break lookForType;
			} else {
				return referenceBinding;
			}
		}

		// Since name could not be found, add a problem binding
		// to the collections so it will be reported as an error next time.
		addNotFoundType(name);
	}

	if (packageBinding == null) { // have not looked for it before
		if ((packageBinding = findPackage(name, mod)) != null) {
			if (!splitPackageAllowed && packageBinding instanceof SplitPackageBinding) {
				return ((SplitPackageBinding) packageBinding).getVisibleFor(mod, false);
			}
			return packageBinding;
		}
		if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
			if (problemBinding != null)
				return problemBinding;
			return referenceBinding; // found cached missing type - check if package conflict
		}
		addNotFoundPackage(name);
	}

	return problemBinding;
}
public final boolean isViewedAsDeprecated() {
	if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
		this.tagBits |= TagBits.DeprecatedAnnotationResolved;
		if (this.compoundName != CharOperation.NO_CHAR_CHAR) {
			ReferenceBinding packageInfo = this.getType(TypeConstants.PACKAGE_INFO_NAME, this.enclosingModule);
			if (packageInfo != null) {
				packageInfo.initializeDeprecatedAnnotationTagBits();
				this.tagBits |= packageInfo.tagBits & TagBits.AllStandardAnnotationsMask;
			}
		}
	}
	return (this.tagBits & TagBits.AnnotationDeprecated) != 0;
}
public int getDefaultNullness() {
	if (this.defaultNullness == NO_NULL_DEFAULT)
		return this.enclosingModule.getDefaultNullness();
	return this.defaultNullness;
}
public void setDefaultNullness(int nullness) {
	this.defaultNullness = nullness;
}
/**
 * Find a binding (either this package or its enclosing ModuleBinding)
 * where 'defaultNullness' matches the given predicate.
 */
public Binding findDefaultNullnessTarget(Predicate<Integer> predicate) {
	if (predicate.test(this.defaultNullness))
		return this;
	if (this.defaultNullness == NO_NULL_DEFAULT)
		if (predicate.test(this.enclosingModule.getDefaultNullness()))
			return this.enclosingModule;
	return null;
}
/* API
* Answer the receiver's binding type from Binding.BindingID.
*/
@Override
public final int kind() {
	return Binding.PACKAGE;
}

@Override
public int problemId() {
	if ((this.tagBits & TagBits.HasMissingType) != 0)
		return ProblemReasons.NotFound;
	return ProblemReasons.NoError;
}


void checkIfNullAnnotationPackage() {
	LookupEnvironment env = this.environment;
	if (env.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
		if (isPackageOfQualifiedTypeName(this.compoundName, env.getNullableAnnotationName()))
			env.nullableAnnotationPackage = this;
		if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullAnnotationName()))
			env.nonnullAnnotationPackage = this;
		if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullByDefaultAnnotationName()))
			env.nonnullByDefaultAnnotationPackage = this;
	}
}
private boolean isPackageOfQualifiedTypeName(char[][] packageName, char[][] typeName) {
	int length;
	if (typeName == null || (length = packageName.length) != typeName.length -1)
		return false;
	for (int i=0; i<length; i++)
		if (!CharOperation.equals(packageName[i], typeName[i]))
			return false;
	return true;
}

void checkIfNullAnnotationType(ReferenceBinding type) {
	// check if type is one of the configured null annotation types
	// if so mark as a well known type using the corresponding typeBit:
	if (this.environment.nullableAnnotationPackage == this
			&& CharOperation.equals(type.compoundName, this.environment.getNullableAnnotationName())) {
		type.typeBits |= TypeIds.BitNullableAnnotation;
		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type
			this.environment.nullableAnnotationPackage = null; // don't check again
	} else if (this.environment.nonnullAnnotationPackage == this
			&& CharOperation.equals(type.compoundName, this.environment.getNonNullAnnotationName())) {
		type.typeBits |= TypeIds.BitNonNullAnnotation;
		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type
			this.environment.nonnullAnnotationPackage = null; // don't check again
	} else if (this.environment.nonnullByDefaultAnnotationPackage == this
			&& CharOperation.equals(type.compoundName, this.environment.getNonNullByDefaultAnnotationName())) {
		type.typeBits |= TypeIds.BitNonNullByDefaultAnnotation;
		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type
			this.environment.nonnullByDefaultAnnotationPackage = null; // don't check again
	} else {
		type.typeBits |= this.environment.getNullAnnotationBit(type.compoundName);
	}
}

@Override
public char[] readableName() /*java.lang*/ {
	return CharOperation.concatWith(this.compoundName, '.');
}
@Override
public String toString() {
	String str;
	if (this.compoundName == CharOperation.NO_CHAR_CHAR) {
		str = "The Default Package"; //$NON-NLS-1$
	} else {
		str = "package " + ((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$
	}
	if ((this.tagBits & TagBits.HasMissingType) != 0) {
		str += "[MISSING]"; //$NON-NLS-1$
	}
	return str;
}
public boolean isDeclaredIn(ModuleBinding moduleBinding) {
	return this.enclosingModule == moduleBinding;
}
public boolean subsumes(PackageBinding binding) {
	return binding == this;
}
/**
 * Is this package exported from its module?
 * Does not consider export restrictions.
 */
public boolean isExported() {
	if (this.isExported == null) {
		if (this.enclosingModule.isAuto) {
			this.isExported = Boolean.TRUE;
		} else {
			this.enclosingModule.getExports(); // ensure resolved and completed
			if (this.isExported == null)
				this.isExported = Boolean.FALSE;
		}
	}
	return this.isExported == Boolean.TRUE;
}
/**
 * If this package is uniquely visible to 'module' return a plain PackageBinding.
 * In case of a conflict between a local package and foreign package
 * the plain local package is returned, because this conflict will more
 * appropriately be reported against the package declaration, not its references.
 * In case of multiple accessible foreign packages a SplitPackageBinding is returned
 * to indicate a conflict.
 */
public PackageBinding getVisibleFor(ModuleBinding module, boolean preferLocal) {
	return this;
}
public boolean hasCompilationUnit(boolean checkCUs) {
	if (this.knownTypes != null) {
		for (ReferenceBinding knownType : this.knownTypes.valueTable) {
			if (knownType != null && knownType != LookupEnvironment.TheNotFoundType)
				return true;
		}
	}
	if (this.environment.useModuleSystem) {
		IModuleAwareNameEnvironment moduleEnv = (IModuleAwareNameEnvironment) this.environment.nameEnvironment;
		return moduleEnv.hasCompilationUnit(this.compoundName, this.enclosingModule.nameForLookup(), checkCUs);
	}
	return false;
}

public void addWrappingSplitPackageBinding(SplitPackageBinding splitPackageBinding) {
	if (this.wrappingSplitPackageBindings == null) {
		this.wrappingSplitPackageBindings = new ArrayList<>();
	}
	this.wrappingSplitPackageBindings.add(splitPackageBinding);
}
}
