/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     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 org.eclipse.jdt.core.compiler.CharOperation;
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;
	public LookupEnvironment environment;
	HashtableOfType knownTypes;
	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}
	protected int defaultNullness = NO_NULL_DEFAULT;

protected PackageBinding() {
	// for creating problem package
}
public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment) {
	this(new char[][] {topLevelPackageName}, null, environment);
}
/* Create the default package.
*/
public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment) {
	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();
}

public PackageBinding(LookupEnvironment environment) {
	this(CharOperation.NO_CHAR_CHAR, null, environment);
}
private 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);
}
void addPackage(PackageBinding element) {
	if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
	this.knownPackages.put(element.compoundName[element.compoundName.length - 1], 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);
}

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
 */
public char[] computeUniqueKey(boolean isLeaf) {
	return CharOperation.concatWith(this.compoundName, '/');
}
private PackageBinding findPackage(char[] name) {
	if (!this.environment.isPackage(this.compoundName, name))
		return null;

	char[][] subPkgCompoundName = CharOperation.arrayConcat(this.compoundName, name);
	PackageBinding subPackageBinding = new PackageBinding(subPkgCompoundName, this, this.environment);
	addPackage(subPackageBinding);
	return subPackageBinding;
}
/* 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) {
	PackageBinding binding = getPackage0(name);
	if (binding != null) {
		if (binding == LookupEnvironment.TheNotFoundPackage)
			return null;
		else
			return binding;
	}
	if ((binding = findPackage(name)) != 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.
*
* NOTE: Senders must convert theNotFoundPackage into a real problem
* package if its to returned.
*/

PackageBinding getPackage0(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) {
	ReferenceBinding referenceBinding = getType0(name);
	if (referenceBinding == null) {
		if ((referenceBinding = this.environment.askForType(this, name)) == 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);
	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) {
	ReferenceBinding referenceBinding = getType0(name);
	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);
		}
		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) {
		return packageBinding;
	}
	if (referenceBinding == null) { // have not looked for it before
		if ((referenceBinding = this.environment.askForType(this, name)) != null) {
			if (referenceBinding.isNestedType()) {
				return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
			}
			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)) != null) {
			return packageBinding;
		}
		if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
			return referenceBinding; // found cached missing type - check if package conflict
		}
		addNotFoundPackage(name);
	}

	return null;
}
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);
			if (packageInfo != null) {
				packageInfo.initializeDeprecatedAnnotationTagBits();
				this.tagBits |= packageInfo.tagBits & TagBits.AllStandardAnnotationsMask;
			}
		}
	}
	return (this.tagBits & TagBits.AnnotationDeprecated) != 0;
}
/* API
* Answer the receiver's binding type from Binding.BindingID.
*/
public final int kind() {
	return Binding.PACKAGE;
}

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);
	}
}

public char[] readableName() /*java.lang*/ {
	return CharOperation.concatWith(this.compoundName, '.');
}
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;
}
}
