/*******************************************************************************
 * Copyright (c) 2013 Christian Pontesegger 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:
 *     Christian Pontesegger - initial API and implementation
 *     Arthur Daussy - Allow optional parameter
 *******************************************************************************/
package org.eclipse.ease.lang.javascript;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.ease.AbstractCodeFactory;
import org.eclipse.ease.IScriptEngine;
import org.eclipse.ease.Logger;
import org.eclipse.ease.modules.EnvironmentModule;
import org.eclipse.ease.modules.IEnvironment;
import org.eclipse.ease.modules.IScriptFunctionModifier;
import org.eclipse.ease.modules.ModuleHelper;
import org.eclipse.ease.tools.StringTools;

public class JavaScriptCodeFactory extends AbstractCodeFactory {

	public static List<String> RESERVED_KEYWORDS = new ArrayList<>();

	static {
		RESERVED_KEYWORDS.add("abstract");
		RESERVED_KEYWORDS.add("arguments");
		RESERVED_KEYWORDS.add("boolean");
		RESERVED_KEYWORDS.add("break");
		RESERVED_KEYWORDS.add("byte");
		RESERVED_KEYWORDS.add("case");
		RESERVED_KEYWORDS.add("catch");
		RESERVED_KEYWORDS.add("char");
		RESERVED_KEYWORDS.add("class");
		RESERVED_KEYWORDS.add("const");
		RESERVED_KEYWORDS.add("continue");
		RESERVED_KEYWORDS.add("debugger");
		RESERVED_KEYWORDS.add("default");
		RESERVED_KEYWORDS.add("delete");
		RESERVED_KEYWORDS.add("do");
		RESERVED_KEYWORDS.add("double");
		RESERVED_KEYWORDS.add("else");
		RESERVED_KEYWORDS.add("enum");
		RESERVED_KEYWORDS.add("eval");
		RESERVED_KEYWORDS.add("export");
		RESERVED_KEYWORDS.add("extends");
		RESERVED_KEYWORDS.add("false");
		RESERVED_KEYWORDS.add("final");
		RESERVED_KEYWORDS.add("finally");
		RESERVED_KEYWORDS.add("float");
		RESERVED_KEYWORDS.add("for");
		RESERVED_KEYWORDS.add("function");
		RESERVED_KEYWORDS.add("goto");
		RESERVED_KEYWORDS.add("if");
		RESERVED_KEYWORDS.add("implements");
		RESERVED_KEYWORDS.add("import");
		RESERVED_KEYWORDS.add("in");
		RESERVED_KEYWORDS.add("instanceof");
		RESERVED_KEYWORDS.add("int");
		RESERVED_KEYWORDS.add("interface");
		RESERVED_KEYWORDS.add("let");
		RESERVED_KEYWORDS.add("long");
		RESERVED_KEYWORDS.add("native");
		RESERVED_KEYWORDS.add("new");
		RESERVED_KEYWORDS.add("null");
		RESERVED_KEYWORDS.add("package");
		RESERVED_KEYWORDS.add("private");
		RESERVED_KEYWORDS.add("protected");
		RESERVED_KEYWORDS.add("public");
		RESERVED_KEYWORDS.add("return");
		RESERVED_KEYWORDS.add("short");
		RESERVED_KEYWORDS.add("static");
		RESERVED_KEYWORDS.add("super");
		RESERVED_KEYWORDS.add("switch");
		RESERVED_KEYWORDS.add("synchronized");
		RESERVED_KEYWORDS.add("this");
		RESERVED_KEYWORDS.add("throw");
		RESERVED_KEYWORDS.add("throws");
		RESERVED_KEYWORDS.add("transient");
		RESERVED_KEYWORDS.add("true");
		RESERVED_KEYWORDS.add("try");
		RESERVED_KEYWORDS.add("typeof");
		RESERVED_KEYWORDS.add("var");
		RESERVED_KEYWORDS.add("void");
		RESERVED_KEYWORDS.add("volatile");
		RESERVED_KEYWORDS.add("while");
		RESERVED_KEYWORDS.add("with");
		RESERVED_KEYWORDS.add("yield");
	}

	private static boolean isValidMethodName(final String methodName) {
		return JavaScriptHelper.isSaveName(methodName) && !RESERVED_KEYWORDS.contains(methodName);
	}

	@Override
	public String classInstantiation(final Class<?> clazz, final String[] parameters) {
		final StringBuilder code = new StringBuilder();
		code.append("new Packages.").append(clazz.getName()).append('(');

		if (parameters != null) {
			for (final String parameter : parameters)
				code.append(parameter).append(", ");

			if (parameters.length > 0)
				code.delete(code.length() - 2, code.length());
		}

		code.append(')');

		return code.toString();
	}

	@Override
	protected String getNullString() {
		return "null";
	}

	@Override
	public String getSaveVariableName(final String variableName) {
		return JavaScriptHelper.getSaveName(variableName);
	}

	private StringBuilder verifyParameters(final List<Parameter> parameters, String indent) {
		final StringBuilder data = new StringBuilder();

		if (!parameters.isEmpty()) {
			final Parameter parameter = parameters.get(parameters.size() - 1);
			data.append(indent).append("if (typeof " + parameter.getName() + " === \"undefined\") {").append(StringTools.LINE_DELIMITER);
			if (parameter.isOptional()) {
				data.append(indent).append("\t" + parameter.getName() + " = " + getDefaultValue(parameter) + ';').append(StringTools.LINE_DELIMITER);
			} else {
				data.append(indent).append("\tthrow 'Parameter <" + parameter.getName() + "> is not optional';").append(StringTools.LINE_DELIMITER);

			}
			data.append(verifyParameters(parameters.subList(0, parameters.size() - 1), indent + "\t"));
			data.append(indent).append('}').append(StringTools.LINE_DELIMITER);
		}

		return data;
	}

	@Override
	public String createCommentedString(String comment, boolean addBlockComment) {
		if (addBlockComment) {
			// beautify block comments by having '*' characters in each line
			final StringBuilder builder = new StringBuilder();
			builder.append("/**").append(StringTools.LINE_DELIMITER);
			for (final String line : comment.split("\\r?\\n"))
				builder.append(" * ").append(line).append(StringTools.LINE_DELIMITER);

			builder.append(" */").append(StringTools.LINE_DELIMITER);

			return builder.toString();

		} else
			return super.createCommentedString(comment, addBlockComment);
	}

	@Override
	public String createWrapper(IEnvironment environment, Object instance, String identifier, boolean customNamespace, IScriptEngine engine) {

		if (customNamespace)
			// create object wrapper
			return createObjectWrapper(environment, instance, identifier);

		else
			return super.createWrapper(environment, instance, identifier, customNamespace, engine);
	}

	private String createObjectWrapper(IEnvironment environment, Object instance, String identifier) {
		final StringBuilder scriptCode = new StringBuilder();

		scriptCode.append(EnvironmentModule.EASE_CODE_PREFIX + "temporary_wrapper_object = {").append(StringTools.LINE_DELIMITER);
		scriptCode.append("\tjavaInstance: ").append(identifier).append(',').append(StringTools.LINE_DELIMITER);

		scriptCode.append(StringTools.LINE_DELIMITER).append("\t// field definitions").append(StringTools.LINE_DELIMITER);
		for (final Field field : ModuleHelper.getFields(instance.getClass())) {
			if (isSupportedByLanguage(field)) {
				scriptCode.append('\t').append(field.getName()).append(": ").append(identifier).append('.').append(field.getName()).append(',')
						.append(StringTools.LINE_DELIMITER);
			}
		}

		scriptCode.append(StringTools.LINE_DELIMITER).append("\t// method definitions").append(StringTools.LINE_DELIMITER);
		for (final Method method : ModuleHelper.getMethods(instance.getClass())) {
			if (isSupportedByLanguage(method)) {

				// parse parameters
				final List<Parameter> parameters = ModuleHelper.getParameters(method);

				final String body = "\t\t" + buildMethodBody(parameters, environment, method, identifier).replaceAll("\n", "\n\t\t");

				// method header
				scriptCode.append('\t').append(method.getName()).append(": function(");
				// method parameters
				scriptCode.append(buildParameterList(parameters)).append(") {").append(StringTools.LINE_DELIMITER);
				// method body
				scriptCode.append(body).append(StringTools.LINE_DELIMITER);
				// method footer
				scriptCode.append("\t},").append(StringTools.LINE_DELIMITER).append(StringTools.LINE_DELIMITER);

				// append method aliases
				for (final String alias : getMethodAliases(method)) {
					if (!isValidMethodName(alias)) {
						Logger.error(PluginConstants.PLUGIN_ID,
								"The method name \"" + alias + "\" from the module \"" + identifier + "\" can not be wrapped because it's name is reserved");

					} else if (!alias.isEmpty()) {
						scriptCode.append('\t').append(alias).append(": function(");
						scriptCode.append(buildParameterList(parameters)).append(") {").append(StringTools.LINE_DELIMITER);
						scriptCode.append("\t\t// method alias").append(StringTools.LINE_DELIMITER);
						scriptCode.append("\t\treturn this.").append(method.getName()).append('(').append(buildParameterList(parameters)).append(");")
								.append(StringTools.LINE_DELIMITER);
						scriptCode.append("\t},").append(StringTools.LINE_DELIMITER).append(StringTools.LINE_DELIMITER);
					}
				}
			}
		}

		scriptCode.append("};").append(StringTools.LINE_DELIMITER);

		return scriptCode.toString();
	}

	@Override
	protected String createFunctionWrapper(final IEnvironment environment, final String moduleVariable, final Method method) {

		final StringBuilder javaScriptCode = new StringBuilder();

		// parse parameters
		final List<Parameter> parameters = ModuleHelper.getParameters(method);

		// build parameter string
		final String parameterList = buildParameterList(parameters);

		final String body = "\t" + buildMethodBody(parameters, environment, method, moduleVariable).replaceAll("\n", "\n\t");

		// build function declarations
		for (final String name : getMethodNames(method)) {
			if (!isValidMethodName(name)) {
				Logger.error(PluginConstants.PLUGIN_ID,
						"The method name \"" + name + "\" from the module \"" + moduleVariable + "\" can not be wrapped because it's name is reserved");

			} else if (!name.isEmpty()) {
				javaScriptCode.append("function ").append(name).append('(').append(parameterList).append(") {").append(StringTools.LINE_DELIMITER);
				javaScriptCode.append(body).append(StringTools.LINE_DELIMITER);
				javaScriptCode.append('}').append(StringTools.LINE_DELIMITER);
			}
		}

		return javaScriptCode.toString();
	}

	private String buildMethodBody(List<Parameter> parameters, IEnvironment environment, Method method, String classIdentifier) {
		final StringBuilder body = new StringBuilder();
		// insert parameter checks
		body.append("// verify mandatory and optional parameters").append(StringTools.LINE_DELIMITER);
		body.append(verifyParameters(parameters, "")).append(StringTools.LINE_DELIMITER);

		// insert hooked pre execution code
		body.append(getPreExecutionCode(environment, method));

		// insert deprecation warnings

		if (ModuleHelper.isDeprecated(method))
			body.append("printError('" + method.getName() + "() is deprecated. Consider updating your code.');").append(StringTools.LINE_DELIMITER);

		// insert method call
		body.append("// delegate call to java layer").append(StringTools.LINE_DELIMITER);
		body.append("var ").append(IScriptFunctionModifier.RESULT_NAME).append(" = ").append(classIdentifier).append('.').append(method.getName()).append('(');
		body.append(buildParameterList(parameters));
		body.append(");").append(StringTools.LINE_DELIMITER);

		// insert hooked post execution code
		body.append(getPostExecutionCode(environment, method));

		// insert return statement
		body.append("return ").append(IScriptFunctionModifier.RESULT_NAME).append(';');

		return body.toString();
	}

	@Override
	protected Object getLanguageIdentifier() {
		return "JavaScript";
	}
}
