/*******************************************************************************
 * Copyright (c) 2013, 2016 Atos and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     Arthur Daussy - initial implementation
 *     Christian Pontesegger - simplified to use base class
 *******************************************************************************/
package org.eclipse.ease.lang.python;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

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

public class PythonCodeFactory extends AbstractCodeFactory {

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

	static {
		RESERVED_KEYWORDS.add("and");
		RESERVED_KEYWORDS.add("as");
		RESERVED_KEYWORDS.add("assert");
		RESERVED_KEYWORDS.add("break");
		RESERVED_KEYWORDS.add("class");
		RESERVED_KEYWORDS.add("continue");
		RESERVED_KEYWORDS.add("def");
		RESERVED_KEYWORDS.add("del");
		RESERVED_KEYWORDS.add("elif");
		RESERVED_KEYWORDS.add("else");
		RESERVED_KEYWORDS.add("except");
		RESERVED_KEYWORDS.add("exec");
		RESERVED_KEYWORDS.add("finally");
		RESERVED_KEYWORDS.add("for");
		RESERVED_KEYWORDS.add("from");
		RESERVED_KEYWORDS.add("global");
		RESERVED_KEYWORDS.add("if");
		RESERVED_KEYWORDS.add("import");
		RESERVED_KEYWORDS.add("in");
		RESERVED_KEYWORDS.add("is");
		RESERVED_KEYWORDS.add("lambda");
		RESERVED_KEYWORDS.add("not");
		RESERVED_KEYWORDS.add("or");
		RESERVED_KEYWORDS.add("pass");
		RESERVED_KEYWORDS.add("print");
		RESERVED_KEYWORDS.add("raise");
		RESERVED_KEYWORDS.add("return");
		RESERVED_KEYWORDS.add("try");
		RESERVED_KEYWORDS.add("while");
		RESERVED_KEYWORDS.add("with");
		RESERVED_KEYWORDS.add("yield");

		// built in functions
		RESERVED_KEYWORDS.add("__import__");
		RESERVED_KEYWORDS.add("abs");
		RESERVED_KEYWORDS.add("all");
		RESERVED_KEYWORDS.add("any");
		RESERVED_KEYWORDS.add("ascii");
		RESERVED_KEYWORDS.add("bin");
		RESERVED_KEYWORDS.add("bool");
		RESERVED_KEYWORDS.add("bytearray");
		RESERVED_KEYWORDS.add("bytes");
		RESERVED_KEYWORDS.add("callable");
		RESERVED_KEYWORDS.add("chr");
		RESERVED_KEYWORDS.add("classmethod");
		RESERVED_KEYWORDS.add("compile");
		RESERVED_KEYWORDS.add("complex");
		RESERVED_KEYWORDS.add("delattr");
		RESERVED_KEYWORDS.add("dict");
		RESERVED_KEYWORDS.add("dir");
		RESERVED_KEYWORDS.add("divmod");
		RESERVED_KEYWORDS.add("enumerate");
		RESERVED_KEYWORDS.add("eval");
		RESERVED_KEYWORDS.add("exec");
		RESERVED_KEYWORDS.add("filter");
		RESERVED_KEYWORDS.add("float");
		RESERVED_KEYWORDS.add("format");
		RESERVED_KEYWORDS.add("frozenset");
		RESERVED_KEYWORDS.add("getattr");
		RESERVED_KEYWORDS.add("globals");
		RESERVED_KEYWORDS.add("hasattr");
		RESERVED_KEYWORDS.add("hash");
		RESERVED_KEYWORDS.add("help");
		RESERVED_KEYWORDS.add("hex");
		RESERVED_KEYWORDS.add("id");
		RESERVED_KEYWORDS.add("input");
		RESERVED_KEYWORDS.add("int");
		RESERVED_KEYWORDS.add("isinstance");
		RESERVED_KEYWORDS.add("issubclass");
		RESERVED_KEYWORDS.add("iter");
		RESERVED_KEYWORDS.add("len");
		RESERVED_KEYWORDS.add("list");
		RESERVED_KEYWORDS.add("locals");
		RESERVED_KEYWORDS.add("map");
		RESERVED_KEYWORDS.add("max");
		RESERVED_KEYWORDS.add("memoryview");
		RESERVED_KEYWORDS.add("min");
		RESERVED_KEYWORDS.add("next");
		RESERVED_KEYWORDS.add("object");
		RESERVED_KEYWORDS.add("oct");
		RESERVED_KEYWORDS.add("open");
		RESERVED_KEYWORDS.add("ord");
		RESERVED_KEYWORDS.add("pow");
		RESERVED_KEYWORDS.add("print");
		RESERVED_KEYWORDS.add("property");
		RESERVED_KEYWORDS.add("range");
		RESERVED_KEYWORDS.add("repr");
		RESERVED_KEYWORDS.add("reversed");
		RESERVED_KEYWORDS.add("round");
		RESERVED_KEYWORDS.add("set");
		RESERVED_KEYWORDS.add("setattr");
		RESERVED_KEYWORDS.add("slice");
		RESERVED_KEYWORDS.add("sorted");
		RESERVED_KEYWORDS.add("staticmethod");
		RESERVED_KEYWORDS.add("str");
		RESERVED_KEYWORDS.add("sum");
		RESERVED_KEYWORDS.add("super");
		RESERVED_KEYWORDS.add("tuple");
		RESERVED_KEYWORDS.add("type");
		RESERVED_KEYWORDS.add("vars");
		RESERVED_KEYWORDS.add("zip");
	}

	private static String toSafeNameStatic(String name) {
		while (RESERVED_KEYWORDS.contains(name))
			name = name + "_";

		return name;
	}

	@Override
	protected String toSafeName(String name) {
		return toSafeNameStatic(name);
	}

	@Override
	protected String createFieldWrapper(IEnvironment environment, String identifier, Field field) {
		final StringBuilder pythonCode = new StringBuilder();

		pythonCode.append("import sys").append(StringTools.LINE_DELIMITER);

		pythonCode.append("if \"py4j\" in sys.modules:").append(StringTools.LINE_DELIMITER);
		pythonCode.append("    ");
		pythonCode.append(field.getName());
		pythonCode.append(" = py4j.java_gateway.get_field(");
		pythonCode.append(identifier);
		pythonCode.append(", \"");
		pythonCode.append(field.getName());
		pythonCode.append("\")");
		pythonCode.append(StringTools.LINE_DELIMITER);

		pythonCode.append("else:").append(StringTools.LINE_DELIMITER);
		pythonCode.append("    ");
		pythonCode.append(field.getName());
		pythonCode.append(" = ");
		pythonCode.append(identifier);
		pythonCode.append(".");
		pythonCode.append(field.getName());
		pythonCode.append(StringTools.LINE_DELIMITER);

		return pythonCode.toString();
	}

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

		final StringBuilder pythonCode = new StringBuilder();

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

		// build parameter string
		final StringBuilder methodSignature = new StringBuilder();
		final StringBuilder methodCall = new StringBuilder();

		for (final Parameter parameter : parameters) {
			methodSignature.append(", ").append(toSafeName(parameter.getName()));
			methodCall.append(", ").append(toSafeName(parameter.getName()));
			if (parameter.isOptional())
				methodSignature.append(" = ").append(getDefaultValue(parameter));
		}

		if (methodSignature.length() > 2) {
			methodSignature.delete(0, 2);
			methodCall.delete(0, 2);
		}

		final String body = buildMethodBody(parameters, method, moduleVariable, environment);

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

			} else if (!name.isEmpty()) {
				pythonCode.append("def ").append(name).append('(').append(methodSignature).append("):\n");
				pythonCode.append(indent(body, "    "));
				pythonCode.append('\n');
				pythonCode.append(name).append(".__ease__ = True\n");
				pythonCode.append('\n');
			}
		}

		return pythonCode.toString();
	}

	private String buildMethodBody(List<Parameter> parameters, Method method, String classIdentifier, IEnvironment environment) {
		final StringBuilder body = new StringBuilder();

		final String methodId = ((EnvironmentModule) environment).registerMethod(method);

		// insert deprecation warnings
		if (ModuleHelper.isDeprecated(method))
			body.append("printError(\"" + method.getName() + "() is deprecated. Consider updating your code.\")").append(StringTools.LINE_DELIMITER);

		// Convert Lists to Java arrays
		body.append(buildArrayConversions(parameters)).append(StringTools.LINE_DELIMITER);

		// check for callbacks
		body.append("if not ").append(EnvironmentModule.getWrappedVariableName(environment)).append(".hasMethodCallback(\"").append(methodId).append("\"):")
				.append(StringTools.LINE_DELIMITER);

		// simple execution
		body.append("    return ").append(classIdentifier).append(".").append(method.getName()).append("(").append(buildParameterList(parameters)).append(")")
				.append(StringTools.LINE_DELIMITER);
		body.append(StringTools.LINE_DELIMITER);

		// execution with callbacks
		body.append("else:").append(StringTools.LINE_DELIMITER);
		if (environment.getScriptEngine().getDescription().getID().startsWith("org.eclipse.ease.lang.python.py4j")) {
			// special handling for Py4J as it cannot use java varargs parameters directly
			body.append("    ").append("parameters_array = gateway.new_array(gateway.jvm.Object, ").append(parameters.size()).append(")")
					.append(StringTools.LINE_DELIMITER);
			for (int index = 0; index < parameters.size(); index++) {
				// Py4J cannot execute
				// gateway.new_array(gateway.jvm.Object, 1)[0] = None
				// as the default value for array elements is null anyway, we simply do not set those
				body.append("    if ").append(toSafeName(parameters.get(index).getName())).append(" != None:").append(StringTools.LINE_DELIMITER);
				body.append("        ").append("parameters_array[").append(index).append("] = ").append(toSafeName(parameters.get(index).getName()))
						.append(StringTools.LINE_DELIMITER);
			}

			body.append("    ").append(EnvironmentModule.getWrappedVariableName(environment)).append(".preMethodCallback(\"").append(methodId)
					.append("\", parameters_array)").append(StringTools.LINE_DELIMITER);

		} else {
			body.append("    ").append(EnvironmentModule.getWrappedVariableName(environment)).append(".preMethodCallback(\"").append(methodId).append("\"")
					.append(parameters.isEmpty() ? "" : ", ").append(buildParameterList(parameters)).append(")").append(StringTools.LINE_DELIMITER);
		}

		body.append("    ").append(RESULT_NAME).append(" = ").append(classIdentifier).append(".").append(method.getName()).append("(")
				.append(buildParameterList(parameters)).append(")").append(StringTools.LINE_DELIMITER);
		body.append("    ").append(EnvironmentModule.getWrappedVariableName(environment)).append(".postMethodCallback(\"").append(methodId).append("\"")
				.append(", ").append(RESULT_NAME).append(")").append(StringTools.LINE_DELIMITER);
		body.append("    return ").append(RESULT_NAME).append(StringTools.LINE_DELIMITER);

		return body.toString();
	}

	private static String indent(String code, String indentation) {
		if (code.isEmpty())
			return code;

		return indentation + code.replaceAll("\n", "\n" + indentation).trim() + "\n";
	}

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

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

		if (parameters != null) {
			for (final String parameter : parameters) {
				code.append(parameter);
				code.append(", ");
			}
			if (parameters.length > 0)
				code.delete(code.length() - 2, code.length());
		}

		code.append(')');

		return code.toString();
	}

	public boolean isValidMethodName(final String methodName) {
		return PythonHelper.isSaveName(methodName) && !RESERVED_KEYWORDS.contains(methodName);
	}

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

	@Override
	protected String getTrueString() {
		return "True";
	}

	@Override
	protected String getFalseString() {
		return "False";
	}

	@Override
	protected String getSingleLineCommentToken() {
		return "# ";
	}

	@Override
	protected String getMultiLineCommentStartToken() {
		return "\"\"\"";
	}

	@Override
	protected String getMultiLineCommentEndToken() {
		return getMultiLineCommentStartToken();
	}

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

	/**
	 * Create wrapper code for Pep302 import statements.
	 *
	 * @param environment
	 *            script environment instance
	 * @param instance
	 *            instance to wrap
	 * @param identifier
	 *            instance identifier to be used
	 * @return wrapper code to be loaded by python
	 */
	public String createPep302WrapperCode(EnvironmentModule environment, Object instance, String identifier) {
		return createWrapper(environment, instance, identifier, false, environment.getScriptEngine());
	}

	/**
	 * Create wrapper code to convert all array parameters to actual Java arrays.
	 *
	 * @param parameters
	 *            List of parameters to create array conversion for.
	 * @return Wrapper code for performing array conversion.
	 */
	protected static String buildArrayConversions(List<Parameter> parameters) {
		return parameters.stream().map(PythonCodeFactory::buildArrayConversion).collect(Collectors.joining(StringTools.LINE_DELIMITER));
	}

	/**
	 * Create wrapper code to convert an array parameter to actual Java array.
	 *
	 * Generated code will have the following look: {@code
	 * 	try:
	 * 		tmp = gateway.new_array([array type], len([value to be converted]))
	 *      for index, value in enumerate([value to be converted]):
	 *          tmp[index] = value
	 *      [value to be converted] = tmp
	 *  except NameError:
	 *      pass
	 *  }
	 *
	 * @param parameter
	 *            Parameter to create conversion code for.
	 * @return Wrapper code for performing array conversion.
	 */
	protected static String buildArrayConversion(Parameter parameter) {
		final StringBuilder builder = new StringBuilder();
		if (parameter.getClazz().isArray()) {
			final String arrayType = getPythonClassIdentifier(parameter.getClazz().getComponentType());
			final String variableName = toSafeNameStatic(parameter.getName());
			builder.append(String.format("if %s is not None:", variableName)).append(StringTools.LINE_DELIMITER);
			builder.append("    try:").append(StringTools.LINE_DELIMITER);
			builder.append(String.format("        tmp = gateway.new_array(%s, len(%s))", arrayType, variableName)).append(StringTools.LINE_DELIMITER);
			builder.append(String.format("        for index, value in enumerate(%s):", variableName)).append(StringTools.LINE_DELIMITER);
			builder.append("            tmp[index] = value").append(StringTools.LINE_DELIMITER);
			builder.append(String.format("        %s =  tmp", variableName)).append(StringTools.LINE_DELIMITER);
			builder.append("    except NameError:").append(StringTools.LINE_DELIMITER);
			builder.append("        pass").append(StringTools.LINE_DELIMITER);
		}
		return builder.toString();
	}

	/**
	 * List of Java primitive types as they need to be handled differently from normal classes when getting their py4j representation.
	 *
	 * bytes are handled differently as Python has native bytearray type.
	 */
	private static final List<Class<?>> PRIMITIVES = Arrays.asList(short.class, int.class, long.class, float.class, double.class, boolean.class, char.class);

	/**
	 * Returns the Python (py4j) identifier for the given class.
	 *
	 * @param cls
	 *            Class to get py4j identifier for.
	 * @return py4j class identifier.
	 */
	protected static String getPythonClassIdentifier(Class<?> cls) {
		if (PRIMITIVES.contains(cls)) {
			return String.format("gateway.jvm.%s", cls.getName());
		} else {
			return cls.getName();
		}
	}
}
