/**********************************************************************
.
.   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
t https://www.eclipse.org/legal/epl-2.0/
t
t SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * IBM - Initial API and implementation
 **********************************************************************/
package org.eclipse.core.tools.nls;

import java.io.*;
import java.util.HashSet;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IType;
import org.eclipse.ltk.core.refactoring.Change;

/**
 * Converts a message bundle file to the new format, and generates a Java
 * file with fields for each key in the bundle.
 */
public class PropertyFileConverter {

	private static final HashSet keywords = new HashSet();

	static {
		keywords.add("abstract"); //$NON-NLS-1$
		keywords.add("assert"); //$NON-NLS-1$
		keywords.add("break"); //$NON-NLS-1$
		keywords.add("case"); //$NON-NLS-1$
		keywords.add("catch"); //$NON-NLS-1$
		keywords.add("class"); //$NON-NLS-1$
		keywords.add("continue"); //$NON-NLS-1$
		keywords.add("default"); //$NON-NLS-1$
		keywords.add("do"); //$NON-NLS-1$
		keywords.add("else"); //$NON-NLS-1$
		keywords.add("extends"); //$NON-NLS-1$
		keywords.add("final"); //$NON-NLS-1$
		keywords.add("finally"); //$NON-NLS-1$
		keywords.add("for"); //$NON-NLS-1$
		keywords.add("if"); //$NON-NLS-1$
		keywords.add("implements"); //$NON-NLS-1$
		keywords.add("import"); //$NON-NLS-1$
		keywords.add("instanceof"); //$NON-NLS-1$
		keywords.add("interface"); //$NON-NLS-1$
		keywords.add("native"); //$NON-NLS-1$
		keywords.add("new"); //$NON-NLS-1$
		keywords.add("package"); //$NON-NLS-1$
		keywords.add("private"); //$NON-NLS-1$
		keywords.add("protected"); //$NON-NLS-1$
		keywords.add("public"); //$NON-NLS-1$
		keywords.add("return"); //$NON-NLS-1$
		keywords.add("static"); //$NON-NLS-1$
		keywords.add("strictfp"); //$NON-NLS-1$
		keywords.add("super"); //$NON-NLS-1$
		keywords.add("switch"); //$NON-NLS-1$
		keywords.add("synchronized"); //$NON-NLS-1$
		keywords.add("this"); //$NON-NLS-1$
		keywords.add("throw"); //$NON-NLS-1$
		keywords.add("throws"); //$NON-NLS-1$
		keywords.add("transient"); //$NON-NLS-1$
		keywords.add("try"); //$NON-NLS-1$
		keywords.add("volatile"); //$NON-NLS-1$
		keywords.add("while"); //$NON-NLS-1$
		keywords.add("true"); //$NON-NLS-1$
		keywords.add("false"); //$NON-NLS-1$
		keywords.add("null"); //$NON-NLS-1$
	}

	/**
	 * Appends the text to put at the end of each Java messages file.
	 */
	private void appendPostText(StringBuilder buffer, String bundlePath, String typeName) {
		buffer.append("\n\tstatic {\n"); //$NON-NLS-1$
		buffer.append("\t\t// load message values from bundle file\n"); //$NON-NLS-1$
		buffer.append("\t\tNLS.initializeMessages(BUNDLE_NAME, "); //$NON-NLS-1$
		buffer.append(typeName);
		buffer.append(".class"); //$NON-NLS-1$
		buffer.append(");\n"); //$NON-NLS-1$
		buffer.append("\t}\n"); //$NON-NLS-1$
		buffer.append("}"); //$NON-NLS-1$
	}

	/**
	 * Appends the text to put at the beginning of each Java messages file.
	 */
	private void appendPreText(StringBuilder buffer, String pkgName, String bundleName, String typeName) {
		//if this text had typos, would it be a false pretext?
		buffer.append("/**********************************************************************\n"); //$NON-NLS-1$
.
.   This\n"); //$NON-NLS-1$
		buffer.append(" * program and the accompanying materials are made available under the terms of\n"); //$NON-NLS-1$
		buffer.append(" * the Eclipse Public License 2.0 which accompanies this distribution, and is\n"); //$NON-NLS-1$
t https://www.eclipse.org/legal/epl-2.0/
t
t SPDX-License-Identifier: EPL-2.0\n"); //$NON-NLS-1$
		buffer.append(" * \n"); //$NON-NLS-1$
		buffer.append(" * Contributors: \n"); //$NON-NLS-1$
		buffer.append(" * IBM - Initial API and implementation\n"); //$NON-NLS-1$
		buffer.append(" **********************************************************************/\n"); //$NON-NLS-1$
		buffer.append("package "); //$NON-NLS-1$
		buffer.append(pkgName);
		buffer.append(";\n\n"); //$NON-NLS-1$

		buffer.append("import org.eclipse.osgi.util.NLS;\n\n"); //$NON-NLS-1$
		buffer.append("public class "); //$NON-NLS-1$
		buffer.append(typeName);
		buffer.append(" extends NLS {\n"); //$NON-NLS-1$
		buffer.append("\tprivate static final String BUNDLE_NAME = \"" + pkgName + '.' + bundleName + "\";//$NON-NLS-1$\n"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/*
	 * Remove the properties in the specified list from the file.
	 */
	public Change trim(IFile propertiesFile, List toDelete) throws IOException, CoreException {
		if (toDelete == null || toDelete.isEmpty())
			return null;
		BufferedReader reader = new BufferedReader(new InputStreamReader(propertiesFile.getContents()));
		StringBuilder bundle = new StringBuilder();

		try {
			String line;
			boolean isContinued = false;
			boolean wasDeleted = false;
			while ((line = reader.readLine()) != null) {
				line = line.trim();
				// just add comments directly to the output
				if (skipLine(line)) {
					bundle.append(line);
					bundle.append("\r\n"); //$NON-NLS-1$
					continue;
				}

				boolean wasContinued = isContinued;
				isContinued = isContinued(line);
				// if we are continued from the previous line...
				if (wasContinued) {
					// if the previous line was deleted then...
					if (wasDeleted) {
						// skip this line
					} else {
						// otherwise write it out
						bundle.append(line);
						bundle.append("\r\n"); //$NON-NLS-1$
					}
				} else {
					// we weren't continued from the previous line
					String key = extractKey(line);
					boolean shouldDelete = toDelete.contains(key);
					// if the key was in our skip list then don't write it out
					if (shouldDelete) {
						wasDeleted = true;
					} else {
						wasDeleted = false;
						bundle.append(line);
						bundle.append("\r\n"); //$NON-NLS-1$
					}
				}

			}
		} finally {
			if (reader != null)
				reader.close();
		}
		NLSFileChange pChange = new NLSFileChange(propertiesFile);
		pChange.setContents(bundle.toString());
		return pChange;
	}

	/**
	 * Reads an old properties file, and creates a new properties file and corresponding
	 * Java messages file.
	 */
	public Change[] convertFile(IType accessorType, IFile propertiesFile) throws IOException, CoreException {
		String pkgName = accessorType.getPackageFragment().getElementName();
		IFile accessorFile = (IFile) accessorType.getCompilationUnit().getCorrespondingResource();
		String typeName = accessorFile.getFullPath().removeFileExtension().lastSegment();
		BufferedReader reader = new BufferedReader(new InputStreamReader(propertiesFile.getContents()));
		String bundleName = propertiesFile.getName();
		StringBuilder clazz = new StringBuilder();
		// convert the bundle resource (messages.properties) to the simple name (messages)
		String simpleBundleName = new Path(bundleName).removeFileExtension().toString();
		appendPreText(clazz, pkgName, simpleBundleName, typeName);
		StringBuilder bundle = new StringBuilder();
		int savings = 0;
		try {
			String line;
			boolean isContinued = false;
			while ((line = reader.readLine()) != null) {
				line = line.trim();
				boolean wasContinued = isContinued;
				isContinued = isContinued(line);
				if (!wasContinued) {
					if (skipLine(line)) {
						clazz.append(convertToComment(line));
					} else {
						String key = extractKey(line);
						savings += 88 + 4 * key.length();
						String identifier = convertToJavaIdentifier(key);
						clazz.append("\tpublic static String "); //$NON-NLS-1$
						clazz.append(identifier);
						clazz.append(";\n"); //$NON-NLS-1$
						//convert the bundle file line to use the Java identifier
						line = identifier + line.substring(key.length());
					}
				}
				//write the line out to the new bundle file
				bundle.append(line);
				bundle.append("\r\n"); //$NON-NLS-1$
			}
		} finally {
			if (reader != null)
				reader.close();
		}
		System.out.println("Memory saved by converting to field-based keys: " + savings);
		appendPostText(clazz, pkgName + '.' + bundleName, typeName);

		NLSFileChange pChange = new NLSFileChange(propertiesFile);
		pChange.setContents(bundle.toString());

		NLSFileChange cChange = new NLSFileChange(accessorFile);
		cChange.setContents(clazz.toString());

		return new Change[] {pChange, cChange};
	}

	/**
	 * Writes the given line as a comment int the provided class buffer.
	 * Blank lines are preserved.
	 */
	private String convertToComment(String line) {
		StringBuilder comment = new StringBuilder();
		if (line.trim().length() > 0) {
			comment.append("\t//"); //$NON-NLS-1$
		}
		int offset = 0;
		//skip leading comment characters
		while (offset < line.length()) {
			char c = line.charAt(offset);
			if (c != '!' && c != '#')
				break;
			offset++;
		}
		comment.append(line.substring(offset));
		comment.append('\n');
		return comment.toString();
	}

	/**
	 * Converts an arbitrary string into a string that represents a valid
	 * Java identifier.
	 */
	public static String convertToJavaIdentifier(String key) {
		String string = key.trim();
		int len = string.length();
		if (len == 0)
			return string;
		StringBuilder result = new StringBuilder();
		char c = string.charAt(0);
		if (Character.isJavaIdentifierStart(c))
			result.append(c);
		else {
			//if it's a valid part, just add an underscore first but keep the character
			result.append('_');
			if (Character.isJavaIdentifierPart(c))
				result.append(c);
		}
		for (int i = 1; i < len; i++) {
			c = string.charAt(i);
			if (Character.isJavaIdentifierPart(c))
				result.append(c);
			else
				result.append('_');
		}
		//preserve trailing space
		if (key.endsWith(" ")) //$NON-NLS-1$
			result.append(' ');
		return makeUnique(result.toString());
	}

	/**
	 * Given a key converted to a Java identifier, ensure it is unique.
	 * @return A unique key
	 */
	private static String makeUnique(String originalKey) {
		String attempt = originalKey;
		int counter = 0;
		while (keywords.contains(attempt))
			attempt = originalKey + counter++;
		return attempt;
	}

	/**
	 * Extracts and returns the property key from the given property file line.
	 * The provided line contains no leading or trailing whitespace.
	 */
	private String extractKey(String line) {
		int len = line.length();
		StringBuilder key = new StringBuilder();
		for (int i = 0; i < len; i++) {
			char c = line.charAt(i);
			//whitespace, colon, or equals characters represent key separators
			if (Character.isWhitespace(c) || c == ':' || c == '=')
				break;
			key.append(c);
		}
		return key.toString();
	}

	/**
	 * Returns whether the property value on this line will be continued onto the next.
	 */
	private boolean isContinued(String line) {
		//note that literal escaped slash characters at the end of a line are not
		//treated as continuation markers.
		boolean continuation = false;
		for (int i = line.length() - 1; (i >= 0) && (line.charAt(i) == '\\'); i--)
			continuation = !continuation;
		return continuation;
	}

	/**
	 * Returns whether the given line contains a key that needs to be converted.
	 */
	private boolean skipLine(String line) {
		if (line.length() == 0)
			return true;
		char first = line.charAt(0);
		return first == '#' || first == '!';
	}
}
