/*******************************************************************************
 * Copyright (c) 2000, 2013 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
 *******************************************************************************/
package org.eclipse.jdt.core;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Commandline.Argument;
import org.apache.tools.ant.util.JavaEnvUtils;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.compiler.util.Util;

/**
 * Ant 1.5 compiler adapter for the Eclipse Java compiler. This adapter permits the
 * Eclipse Java compiler to be used with the <code>javac</code> task in Ant scripts. In order
 * to use it, just set the property <code>build.compiler</code> as follows:
 * <p>
 * <code>&lt;property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/&gt;</code>
 * </p>
 * <p>
 * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
 * </p>
 *
 * @since 2.0
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class JDTCompilerAdapter extends DefaultCompilerAdapter {
	private static final char[] SEPARATOR_CHARS = new char[] { '/', '\\' };
	private static final char[] ADAPTER_PREFIX = "#ADAPTER#".toCharArray(); //$NON-NLS-1$
	private static final char[] ADAPTER_ENCODING = "ENCODING#".toCharArray(); //$NON-NLS-1$
	private static final char[] ADAPTER_ACCESS = "ACCESS#".toCharArray(); //$NON-NLS-1$
	private static String compilerClass = "org.eclipse.jdt.internal.compiler.batch.Main"; //$NON-NLS-1$
	String logFileName;
	Map customDefaultOptions;
	private Map fileEncodings = null;
	private Map dirEncodings = null;
	private List accessRules = null;

	/**
	 * Performs a compile using the JDT batch compiler
	 * @throws BuildException if anything wrong happen during the compilation
	 * @return boolean true if the compilation is ok, false otherwise
	 */
	@Override
	public boolean execute() throws BuildException {
		this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.usingJDTCompiler"), Project.MSG_VERBOSE); //$NON-NLS-1$
		Commandline cmd = setupJavacCommand();

		try {
			Class c = Class.forName(compilerClass);
			Constructor batchCompilerConstructor = c.getConstructor(new Class[] { PrintWriter.class, PrintWriter.class, Boolean.TYPE, Map.class});
			Object batchCompilerInstance = batchCompilerConstructor.newInstance(new Object[] {new PrintWriter(System.out), new PrintWriter(System.err), Boolean.TRUE, this.customDefaultOptions});
			Method compile = c.getMethod("compile", new Class[] {String[].class}); //$NON-NLS-1$
			Object result = compile.invoke(batchCompilerInstance, new Object[] { cmd.getArguments()});
			final boolean resultValue = ((Boolean) result).booleanValue();
			if (!resultValue && this.logFileName != null) {
				this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); //$NON-NLS-1$
			}
			return resultValue;
		} catch (ClassNotFoundException cnfe) {
			throw new BuildException(AntAdapterMessages.getString("ant.jdtadapter.error.cannotFindJDTCompiler"), cnfe); //$NON-NLS-1$
		} catch (Exception ex) {
			throw new BuildException(ex);
		}
	}


	@Override
	protected Commandline setupJavacCommand() throws BuildException {
		Commandline cmd = new Commandline();
		this.customDefaultOptions = new CompilerOptions().getMap();

		Class javacClass = Javac.class;

		/*
		 * Read in the compiler arguments first since we might need to modify
		 * the classpath if any access rules were specified
		 */
		String [] compilerArgs = processCompilerArguments(javacClass);

		/*
		 * This option is used to never exit at the end of the ant task.
		 */
		cmd.createArgument().setValue("-noExit"); //$NON-NLS-1$

		if (this.bootclasspath != null) {
			cmd.createArgument().setValue("-bootclasspath"); //$NON-NLS-1$
			if (this.bootclasspath.size() != 0) {
				/*
				 * Set the bootclasspath for the Eclipse compiler.
				 */
				cmd.createArgument().setPath(this.bootclasspath);
			} else {
				cmd.createArgument().setValue(Util.EMPTY_STRING);
			}
		}

		/*
		 * Eclipse compiler doesn't support -extdirs.
		 * It is emulated using the classpath. We add extdirs entries after the
		 * bootclasspath.
		 */
		if (this.extdirs != null) {
			cmd.createArgument().setValue("-extdirs"); //$NON-NLS-1$
			cmd.createArgument().setPath(this.extdirs);
		}

		Path classpath = new Path(this.project);
		/*
		 * The java runtime is already handled, so we simply want to retrieve the
		 * ant runtime and the compile classpath.
		 */
		classpath.append(getCompileClasspath());
		/*
		 * Set the classpath for the Eclipse compiler.
		 */
		cmd.createArgument().setValue("-classpath"); //$NON-NLS-1$
		createClasspathArgument(cmd, classpath);

		// For -sourcepath, use the "sourcepath" value if present.
		// Otherwise default to the "srcdir" value.
		Path sourcepath = null;

		// retrieve the method getSourcepath() using reflect
		// This is done to improve the compatibility to ant 1.5
		Method getSourcepathMethod = null;
		try {
			getSourcepathMethod = javacClass.getMethod("getSourcepath", (Class[]) null); //$NON-NLS-1$
		} catch(NoSuchMethodException e) {
			// if not found, then we cannot use this method (ant 1.5)
		}
		Path compileSourcePath = null;
		if (getSourcepathMethod != null) {
			try {
				compileSourcePath = (Path) getSourcepathMethod.invoke(this.attributes, (Object[]) null);
			} catch (IllegalAccessException e) {
				// should never happen
			} catch (InvocationTargetException e) {
				// should never happen
			}
		}
		if (compileSourcePath != null) {
			sourcepath = compileSourcePath;
		} else {
			sourcepath = this.src;
		}
		cmd.createArgument().setValue("-sourcepath"); //$NON-NLS-1$
		createClasspathArgument(cmd, sourcepath);

		final String javaVersion = JavaEnvUtils.getJavaVersion();
		String memoryParameterPrefix = javaVersion.equals(JavaEnvUtils.JAVA_1_1) ? "-J-" : "-J-X";//$NON-NLS-1$//$NON-NLS-2$
		if (this.memoryInitialSize != null) {
			if (!this.attributes.isForkedJavac()) {
				this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryInitialSize"), Project.MSG_WARN); //$NON-NLS-1$
			} else {
				cmd.createArgument().setValue(memoryParameterPrefix
						+ "ms" + this.memoryInitialSize); //$NON-NLS-1$
			}
		}

		if (this.memoryMaximumSize != null) {
			if (!this.attributes.isForkedJavac()) {
				this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryMaximumSize"), Project.MSG_WARN); //$NON-NLS-1$
			} else {
				cmd.createArgument().setValue(memoryParameterPrefix
						+ "mx" + this.memoryMaximumSize); //$NON-NLS-1$
			}
		}

		if (this.debug) {
			// retrieve the method getSourcepath() using reflect
			// This is done to improve the compatibility to ant 1.5
			Method getDebugLevelMethod = null;
			try {
				getDebugLevelMethod = javacClass.getMethod("getDebugLevel", (Class[]) null); //$NON-NLS-1$
			} catch(NoSuchMethodException e) {
				// if not found, then we cannot use this method (ant 1.5)
				// debug level is only available with ant 1.5.x
			}
			String debugLevel = null;
			if (getDebugLevelMethod != null) {
				try {
					debugLevel = (String) getDebugLevelMethod.invoke(this.attributes, (Object[]) null);
				} catch (IllegalAccessException e) {
					// should never happen
				} catch (InvocationTargetException e) {
					// should never happen
				}
			}
			if (debugLevel != null) {
				this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
				this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
				this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE);
				if (debugLevel.length() != 0) {
					if (debugLevel.indexOf("vars") != -1) {//$NON-NLS-1$
						this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
					}
					if (debugLevel.indexOf("lines") != -1) {//$NON-NLS-1$
						this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
					}
					if (debugLevel.indexOf("source") != -1) {//$NON-NLS-1$
						this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE);
					}
				}
			} else {
				this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
				this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
				this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE);
			}
		} else {
			this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
			this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
			this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE);
		}

		/*
		 * Handle the nowarn option. If none, then we generate all warnings.
		 */
		if (this.attributes.getNowarn()) {
			// disable all warnings
			Object[] entries = this.customDefaultOptions.entrySet().toArray();
			for (int i = 0, max = entries.length; i < max; i++) {
				Map.Entry entry = (Map.Entry) entries[i];
				if (!(entry.getKey() instanceof String))
					continue;
				if (!(entry.getValue() instanceof String))
					continue;
				if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) {
					this.customDefaultOptions.put(entry.getKey(), CompilerOptions.IGNORE);
				}
			}
			this.customDefaultOptions.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
			if (this.deprecation) {
				this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
				this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
				this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
			}
		} else if (this.deprecation) {
			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
		} else {
			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED);
			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED);
		}

		/*
		 * destDir option.
		 */
		if (this.destDir != null) {
			cmd.createArgument().setValue("-d"); //$NON-NLS-1$
			cmd.createArgument().setFile(this.destDir.getAbsoluteFile());
		}

		/*
		 * verbose option
		 */
		if (this.verbose) {
			cmd.createArgument().setValue("-verbose"); //$NON-NLS-1$
		}

		/*
		 * failnoerror option
		 */
		if (!this.attributes.getFailonerror()) {
			cmd.createArgument().setValue("-proceedOnError"); //$NON-NLS-1$
		}

		/*
		 * target option.
		 */
		if (this.target != null) {
			this.customDefaultOptions.put(CompilerOptions.OPTION_TargetPlatform, this.target);
		}

		/*
		 * source option
		 */
		String source = this.attributes.getSource();
		if (source != null) {
			this.customDefaultOptions.put(CompilerOptions.OPTION_Source, source);
			this.customDefaultOptions.put(CompilerOptions.OPTION_Compliance, source);
		}

		if (compilerArgs != null) {
			/*
			 * Add extra argument on the command line
			 */
			final int length = compilerArgs.length;
			if (length != 0) {
				for (int i = 0, max = length; i < max; i++) {
					String arg = compilerArgs[i];
					if (this.logFileName == null && "-log".equals(arg) && ((i + 1) < max)) { //$NON-NLS-1$
						this.logFileName = compilerArgs[i + 1];
					}
					cmd.createArgument().setValue(arg);
				}
			}
		}
		/*
		 * encoding option. javac task encoding property must be the last encoding on the command
		 * line as compiler arg might also specify an encoding.
		 */
		if (this.encoding != null) {
			cmd.createArgument().setValue("-encoding"); //$NON-NLS-1$
			cmd.createArgument().setValue(this.encoding);
		}

		/*
		 * Eclipse compiler doesn't have a -sourcepath option. This is
		 * handled through the javac task that collects all source files in
		 * srcdir option.
		 */
		logAndAddFilesToCompile(cmd);
		return cmd;
	}

	/**
	 * Get the compiler arguments
	 * @param javacClass
	 * @return String[] the array of arguments
	 */
	private String[] processCompilerArguments(Class javacClass) {
		// retrieve the method getCurrentCompilerArgs() using reflect
		// This is done to improve the compatibility to ant 1.5
		Method getCurrentCompilerArgsMethod = null;
		try {
			getCurrentCompilerArgsMethod = javacClass.getMethod("getCurrentCompilerArgs", (Class[]) null); //$NON-NLS-1$
		} catch (NoSuchMethodException e) {
			// if not found, then we cannot use this method (ant 1.5)
			// debug level is only available with ant 1.5.x
		}
		String[] compilerArgs = null;
		if (getCurrentCompilerArgsMethod != null) {
			try {
				compilerArgs = (String[]) getCurrentCompilerArgsMethod.invoke(this.attributes, (Object[]) null);
			} catch (IllegalAccessException e) {
				// should never happen
			} catch (InvocationTargetException e) {
				// should never happen
			}
		}
		//check the compiler arguments for anything requiring extra processing
		if (compilerArgs != null) checkCompilerArgs(compilerArgs);
		return compilerArgs;
	}
	/**
	 * check the compiler arguments.
	 * Extract from files specified using @, lines marked with ADAPTER_PREFIX
	 * These lines specify information that needs to be interpreted by us.
	 * @param args compiler arguments to process
	 */
	private void checkCompilerArgs(String[] args) {
		for (int i = 0; i < args.length; i++) {
			if (args[i].charAt(0) == '@') {
				try {
					char[] content = Util.getFileCharContent(new File(args[i].substring(1)), null);
					int offset = 0;
					int prefixLength = ADAPTER_PREFIX.length;
					while ((offset = CharOperation.indexOf(ADAPTER_PREFIX, content, true, offset)) > -1) {
						int start = offset + prefixLength;
						int end = CharOperation.indexOf('\n', content, start);
						if (end == -1)
							end = content.length;
						while (CharOperation.isWhitespace(content[end])) {
							end--;
						}

						// end is inclusive, but in the API end is exclusive
						if (CharOperation.equals(ADAPTER_ENCODING, content, start, start + ADAPTER_ENCODING.length)) {
							CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, end + 1);
							// file or folder level custom encoding
							start += ADAPTER_ENCODING.length;
							int encodeStart = CharOperation.lastIndexOf('[', content, start, end);
							if (start < encodeStart && encodeStart < end) {
								boolean isFile = CharOperation.equals(SuffixConstants.SUFFIX_java, content, encodeStart - 5, encodeStart, false);

								String str = String.valueOf(content, start, encodeStart - start);
								String enc = String.valueOf(content, encodeStart, end - encodeStart + 1);
								if (isFile) {
									if (this.fileEncodings == null)
										this.fileEncodings = new HashMap();
									//use File to translate the string into a path with the correct File.seperator
									this.fileEncodings.put(str, enc);
								} else {
									if (this.dirEncodings == null)
										this.dirEncodings = new HashMap();
									this.dirEncodings.put(str, enc);
								}
							}
						} else if (CharOperation.equals(ADAPTER_ACCESS, content, start, start + ADAPTER_ACCESS.length)) {
							// access rules for the classpath
							start += ADAPTER_ACCESS.length;
							int accessStart = CharOperation.indexOf('[', content, start, end);
							CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, accessStart);
							if (start < accessStart && accessStart < end) {
								String path = String.valueOf(content, start, accessStart - start);
								String access = String.valueOf(content, accessStart, end - accessStart + 1);
								if (this.accessRules == null)
									this.accessRules = new ArrayList();
								this.accessRules.add(path);
								this.accessRules.add(access);
							}
						}
						offset = end;
					}
				} catch (IOException e) {
					//ignore
				}
			}
		}

	}

	/**
	 * Copy the classpath to the command line with access rules included.
	 * @param cmd the given command line
	 * @param classpath the given classpath entry
	 */
	private void createClasspathArgument(Commandline cmd, Path classpath) {
		Argument arg = cmd.createArgument();
		final String[] pathElements = classpath.list();

		// empty path return empty string
		if (pathElements.length == 0) {
			arg.setValue(Util.EMPTY_STRING);
			return;
		}

		// no access rules, can set the path directly
		if (this.accessRules == null) {
			arg.setPath(classpath);
			return;
		}

		int rulesLength = this.accessRules.size();
		String[] rules = (String[]) this.accessRules.toArray(new String[rulesLength]);
		int nextRule = 0;
		final StringBuffer result = new StringBuffer();

		//access rules are expected in the same order as the classpath, but there could
		//be elements in the classpath not in the access rules or access rules not in the classpath
		for (int i = 0, max = pathElements.length; i < max; i++) {
			if (i > 0)
				result.append(File.pathSeparatorChar);
			String pathElement = pathElements[i];
			result.append(pathElement);
			//the rules list is [path, rule, path, rule, ...]
			for (int j = nextRule; j < rulesLength; j += 2) {
				String rule = rules[j];
				if (pathElement.endsWith(rule)) {
					result.append(rules[j + 1]);
					nextRule = j + 2;
					break;
				}
				// if the path doesn't match, it could be due to a trailing file separatorChar in the rule
				if (rule.endsWith(File.separator)) {
					// rule ends with the File.separator, but pathElement might not
					// otherwise it would match on the first endsWith
					int ruleLength = rule.length();
					if (pathElement.regionMatches(false, pathElement.length() - ruleLength + 1, rule, 0, ruleLength - 1)) {
						result.append(rules[j + 1]);
						nextRule = j + 2;
						break;
					}
				} else if (pathElement.endsWith(File.separator)) {
					// rule doesn't end with the File.separator, but pathElement might
					int ruleLength = rule.length();
					if (pathElement.regionMatches(false, pathElement.length() - ruleLength - 1, rule, 0, ruleLength)) {
						result.append(rules[j + 1]);
						nextRule = j + 2;
						break;
					}
				}
			}
		}

		arg.setValue(result.toString());
	}
	/**
	 * Modified from base class, Logs the compilation parameters, adds the files
	 * to compile and logs the &quot;niceSourceList&quot;
	 * Appends encoding information at the end of arguments
	 *
	 * @param cmd the given command line
	 */
	@Override
	protected void logAndAddFilesToCompile(Commandline cmd) {
		this.attributes.log("Compilation " + cmd.describeArguments(), //$NON-NLS-1$
				Project.MSG_VERBOSE);

		StringBuffer niceSourceList = new StringBuffer("File"); //$NON-NLS-1$
		if (this.compileList.length != 1) {
			niceSourceList.append("s"); //$NON-NLS-1$
		}
		niceSourceList.append(" to be compiled:"); //$NON-NLS-1$
		niceSourceList.append(System.lineSeparator());

		String[] encodedFiles = null, encodedDirs = null;
		int encodedFilesLength = 0, encodedDirsLength = 0;
		if (this.fileEncodings != null) {
			encodedFilesLength = this.fileEncodings.size();
			encodedFiles = new String[encodedFilesLength];
			this.fileEncodings.keySet().toArray(encodedFiles);
		}
		if (this.dirEncodings != null) {
			encodedDirsLength = this.dirEncodings.size();
			encodedDirs = new String[encodedDirsLength];
			this.dirEncodings.keySet().toArray(encodedDirs);
			//we need the directories sorted, longest first,since sub directories can
			//override encodings for their parent directories
			Comparator comparator = new Comparator() {
				@Override
				public int compare(Object o1, Object o2) {
					return ((String) o2).length() - ((String) o1).length();
				}
			};
			Arrays.sort(encodedDirs, comparator);
		}

		for (int i = 0; i < this.compileList.length; i++) {
			String arg = this.compileList[i].getAbsolutePath();
			boolean encoded = false;
			if (encodedFiles != null) {
				//check for file level custom encoding
				for (int j = 0; j < encodedFilesLength; j++) {
					if (arg.endsWith(encodedFiles[j])) {
						//found encoding, remove it from the list to speed things up next time around
						arg = arg + (String) this.fileEncodings.get(encodedFiles[j]);
						if (j < encodedFilesLength - 1) {
							System.arraycopy(encodedFiles, j + 1, encodedFiles, j, encodedFilesLength - j - 1);
						}
						encodedFiles[--encodedFilesLength] = null;
						encoded = true;
						break;
					}
				}
			}
			if (!encoded && encodedDirs != null) {
				//check folder level custom encoding
				for (int j = 0; j < encodedDirsLength; j++) {
					if (arg.lastIndexOf(encodedDirs[j]) != -1) {
						arg = arg + (String) this.dirEncodings.get(encodedDirs[j]);
						break;
					}
				}
			}
			cmd.createArgument().setValue(arg);
			niceSourceList.append("    " + arg + System.lineSeparator()); //$NON-NLS-1$
		}

		this.attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
	}
}
