/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contribution for
 *								Bug 440687 - [compiler][batch][null] improve command line option for external annotations
 *     Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
 *     						Bug 473178
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.Util;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ClasspathDirectory extends ClasspathLocation {

private Hashtable directoryCache;
private String[] missingPackageHolder = new String[1];
private int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
private String encoding; // only useful if referenced in the source path
private Hashtable<String, Hashtable<String, String>> packageSecondaryTypes = null;
Map options;

ClasspathDirectory(File directory, String encoding, int mode,
		AccessRuleSet accessRuleSet, String destinationPath, Map options) {
	super(accessRuleSet, destinationPath);
	this.mode = mode;
	this.options = options;
	try {
		this.path = directory.getCanonicalPath();
	} catch (IOException e) {
		// should not happen as we know that the file exists
		this.path = directory.getAbsolutePath();
	}
	if (!this.path.endsWith(File.separator))
		this.path += File.separator;
	this.directoryCache = new Hashtable(11);
	this.encoding = encoding;
}
String[] directoryList(String qualifiedPackageName) {
	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
	if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
	if (dirList != null) return dirList;

	File dir = new File(this.path + qualifiedPackageName);
	notFound : if (dir.isDirectory()) {
		// must protect against a case insensitive File call
		// walk the qualifiedPackageName backwards looking for an uppercase character before the '/'
		int index = qualifiedPackageName.length();
		int last = qualifiedPackageName.lastIndexOf(File.separatorChar);
		while (--index > last && !ScannerHelper.isUpperCase(qualifiedPackageName.charAt(index))){/*empty*/}
		if (index > last) {
			if (last == -1) {
				if (!doesFileExist(qualifiedPackageName, Util.EMPTY_STRING))
					break notFound;
			} else {
				String packageName = qualifiedPackageName.substring(last + 1);
				String parentPackage = qualifiedPackageName.substring(0, last);
				if (!doesFileExist(packageName, parentPackage))
					break notFound;
			}
		}
		if ((dirList = dir.list()) == null)
			dirList = CharOperation.NO_STRINGS;
		this.directoryCache.put(qualifiedPackageName, dirList);
		return dirList;
	}
	this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder);
	return null;
}
boolean doesFileExist(String fileName, String qualifiedPackageName) {
	String[] dirList = directoryList(qualifiedPackageName);
	if (dirList == null) return false; // most common case

	for (int i = dirList.length; --i >= 0;)
		if (fileName.equals(dirList[i]))
			return true;
	return false;
}
public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
	return null;
}
private NameEnvironmentAnswer findClassInternal(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
	if (!isPackage(qualifiedPackageName, null)) return null; // most common case TODO(SHMOD): use module name from this.module?
	String fileName = new String(typeName);
	boolean binaryExists = ((this.mode & BINARY) != 0) && doesFileExist(fileName + SUFFIX_STRING_class, qualifiedPackageName);
	boolean sourceExists = ((this.mode & SOURCE) != 0) && doesFileExist(fileName + SUFFIX_STRING_java, qualifiedPackageName);
	if (sourceExists && !asBinaryOnly) {
		String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6)  + SUFFIX_STRING_java;
		CompilationUnit unit = new CompilationUnit(null, fullSourcePath, this.encoding, this.destinationPath);
		unit.module = this.module == null ? null : this.module.name();
		if (!binaryExists)
			return new NameEnvironmentAnswer(new CompilationUnit(null,
					fullSourcePath, this.encoding, this.destinationPath),
					fetchAccessRestriction(qualifiedBinaryFileName));
		String fullBinaryPath = this.path + qualifiedBinaryFileName;
		long binaryModified = new File(fullBinaryPath).lastModified();
		long sourceModified = new File(fullSourcePath).lastModified();
		if (sourceModified > binaryModified)
			return new NameEnvironmentAnswer(new CompilationUnit(null,
					fullSourcePath, this.encoding, this.destinationPath),
					fetchAccessRestriction(qualifiedBinaryFileName));
	}
	if (binaryExists) {
		try {
			ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName);
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=321115, package names are to be treated case sensitive.
			String typeSearched = qualifiedPackageName.length() > 0 ? 
					qualifiedPackageName.replace(File.separatorChar, '/') + "/" + fileName //$NON-NLS-1$
					: fileName;
			if (!CharOperation.equals(reader.getName(), typeSearched.toCharArray())) {
				reader = null;
			}
			if (reader != null) {
				char[] modName = reader.moduleName != null ? reader.moduleName : this.module != null ? this.module.name() : null;
				return new NameEnvironmentAnswer(
						reader,
						fetchAccessRestriction(qualifiedBinaryFileName),
						modName);
			}
		} catch (IOException e) {
			// treat as if file is missing
		} catch (ClassFormatException e) {
			// treat as if file is missing
		}
	}
	return null;
}
public NameEnvironmentAnswer findSecondaryInClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
	//"package-info" is a reserved class name and can never be a secondary type (it is much faster to stop the search here).
	if(TypeConstants.PACKAGE_INFO_NAME.equals(typeName)) {
		return null;
	}

	String typeNameString = new String(typeName);
	String moduleName = this.module != null ? String.valueOf(this.module.name()) : null; // TODO(SHMOD): test for ModuleBinding.ANY & UNNAMED
	boolean prereqs = this.options != null && isPackage(qualifiedPackageName, moduleName) && ((this.mode & SOURCE) != 0) && doesFileExist(typeNameString + SUFFIX_STRING_java, qualifiedPackageName);
	return prereqs ? null : findSourceSecondaryType(typeNameString, qualifiedPackageName, qualifiedBinaryFileName); /* only secondary types */
}

@Override
public boolean hasAnnotationFileFor(String qualifiedTypeName) {
	int pos = qualifiedTypeName.lastIndexOf('/');
	if (pos != -1 && (pos + 1 < qualifiedTypeName.length())) {
		String fileName = qualifiedTypeName.substring(pos + 1) + ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX;
		return doesFileExist(fileName, qualifiedTypeName.substring(0, pos));
	}
	return false;
}
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String moduleName, String qualifiedBinaryFileName) {
	return findClass(typeName, qualifiedPackageName, moduleName, qualifiedBinaryFileName, false);
}
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String moduleName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
	if (File.separatorChar == '/')
      return findClassInternal(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly);

	return findClassInternal(typeName, qualifiedPackageName.replace('/', File.separatorChar),
				qualifiedBinaryFileName.replace('/', File.separatorChar), asBinaryOnly);
}
/**
 *  Add all the secondary types in the package
 */
private Hashtable<String, String> getSecondaryTypes(String qualifiedPackageName) {
	Hashtable<String, String> packageEntry = new Hashtable<>();

	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
	if (dirList == this.missingPackageHolder // package exists in another classpath directory or jar 
			|| dirList == null) 
		return packageEntry;

	File dir = new File(this.path + qualifiedPackageName);
	File[] listFiles = dir.isDirectory() ? dir.listFiles() : null;
	if (listFiles == null) return packageEntry;

	for (int i = 0, l = listFiles.length; i < l; ++i) {
		File f = listFiles[i];
		if (f.isDirectory()) continue;
		String s = f.getAbsolutePath();
		if (s == null) continue;
		if (!(s.endsWith(SUFFIX_STRING_java) || s.endsWith(SUFFIX_STRING_JAVA))) continue;
		CompilationUnit cu = new CompilationUnit(null, s, this.encoding, this.destinationPath);
		CompilationResult compilationResult = new CompilationResult(s.toCharArray(), 1, 1, 10);
		ProblemReporter problemReporter = 
				new ProblemReporter(
					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
					new CompilerOptions(this.options),
					new DefaultProblemFactory());
		Parser parser = new Parser(problemReporter, false);
		parser.reportSyntaxErrorIsRequired = false;

		CompilationUnitDeclaration unit = parser.parse(cu, compilationResult);
		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit != null ? unit.types : null;
		if (types == null) continue;
		for (int j = 0, k = types.length; j < k; j++) {
			TypeDeclaration type = types[j];
			char[] name = type.isSecondary() ? type.name : null;  // add only secondary types
			if (name != null) 
				packageEntry.put(new String(name), s);
		}
	}
	return packageEntry;
}
private NameEnvironmentAnswer findSourceSecondaryType(String typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
	
	if (this.packageSecondaryTypes == null) this.packageSecondaryTypes = new Hashtable<>();
	Hashtable<String, String> packageEntry = this.packageSecondaryTypes.get(qualifiedPackageName);
	if (packageEntry == null) {
		packageEntry = 	getSecondaryTypes(qualifiedPackageName);
		this.packageSecondaryTypes.put(qualifiedPackageName, packageEntry);
	}
	String fileName = packageEntry.get(typeName);
	return fileName != null ? new NameEnvironmentAnswer(new CompilationUnit(null,
			fileName, this.encoding, this.destinationPath),
			fetchAccessRestriction(qualifiedBinaryFileName)) : null;
}


public char[][][] findTypeNames(String qualifiedPackageName, String moduleName) {
	if (!isPackage(qualifiedPackageName, moduleName)) {
		return null; // most common case
	}
	File dir = new File(this.path + qualifiedPackageName);
	if (!dir.exists() || !dir.isDirectory()) {
		return null;
	}
	String[] listFiles = dir.list(new FilenameFilter() {
		public boolean accept(File directory1, String name) {
			String fileName = name.toLowerCase();
			return fileName.endsWith(".class") || fileName.endsWith(".java"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	});
	int length;
	if (listFiles == null || (length = listFiles.length) == 0) {
		return null;
	}
	Set<String> secondary = getSecondaryTypes(qualifiedPackageName).keySet();
	char[][][] result = new char[length + secondary.size()][][];
	char[][] packageName = CharOperation.splitOn(File.separatorChar, qualifiedPackageName.toCharArray());
	for (int i = 0; i < length; i++) {
		String fileName = listFiles[i];
		int indexOfLastDot = fileName.indexOf('.');
		String typeName = indexOfLastDot > 0 ? fileName.substring(0, indexOfLastDot) : fileName;
		result[i] = CharOperation.arrayConcat(packageName, typeName.toCharArray());
	}
	if (secondary.size() > 0) {
		int idx = length;
		for (String type : secondary) {
			result[idx++] = CharOperation.arrayConcat(packageName, type.toCharArray());
		}
	}
	return result;
}
public void initialize() throws IOException {
	// nothing to do
}
public char[][] getModulesDeclaringPackage(String qualifiedPackageName, /*@Nullable*/String moduleName) {
	String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
	return singletonModuleNameIf(directoryList(qp2) != null);
}
@Override
public boolean hasCompilationUnit(String qualifiedPackageName, String moduleName) {
	String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
	String[] dirList = directoryList(qp2);
	if (dirList != null) {
		for (String entry : dirList) {
			String entryLC = entry.toLowerCase();
			if (entryLC.endsWith(SUFFIX_STRING_java) || entryLC.endsWith(SUFFIX_STRING_class))
				return true;
		}
	}
	return false;
}
public boolean hasCUDeclaringPackage(String qualifiedPackageName, Function<CompilationUnit, String> pkgNameExtractor) {
	String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
	return Stream.of(directoryList(qp2)).anyMatch(entry -> {
		String entryLC = entry.toLowerCase();
		boolean hasDeclaration = false;
		String fullPath = this.path + qp2 + "/" + entryLC; //$NON-NLS-1$
		String pkgName = null;
		if (entryLC.endsWith(SUFFIX_STRING_class)) {
			return true;
		} else if (entryLC.endsWith(SUFFIX_STRING_java)) {
			CompilationUnit cu = new CompilationUnit(null, fullPath, this.encoding);
			pkgName = pkgNameExtractor.apply(cu);
		}
		if (pkgName != null && pkgName.equals(qualifiedPackageName))
			hasDeclaration = true;
		return hasDeclaration;
	});
}
public void reset() {
	this.directoryCache = new Hashtable(11);
}
public String toString() {
	return "ClasspathDirectory " + this.path; //$NON-NLS-1$
}
public char[] normalizedPath() {
	if (this.normalizedPath == null) {
		this.normalizedPath = this.path.toCharArray();
		if (File.separatorChar == '\\') {
			CharOperation.replace(this.normalizedPath, '\\', '/');
		}
	}
	return this.normalizedPath;
}
public String getPath() {
	return this.path;
}
public int getMode() {
	return this.mode;
}
public IModule getModule() {
	if (this.isAutoModule && this.module == null) {
		return this.module = IModule.createAutomatic(this.path, false, null/*no manifest*/);
	}
	return this.module;
}
}
