/*********************************************************************
 * Copyright (c) 2018 The University of York.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.epsilon.eol.cli;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.apache.commons.cli.Option;
import org.eclipse.epsilon.common.cli.ConfigParser;
import org.eclipse.epsilon.common.util.FileUtil;
import org.eclipse.epsilon.common.util.StringProperties;
import org.eclipse.epsilon.common.util.StringUtil;
import org.eclipse.epsilon.eol.models.IModel;
import org.eclipse.epsilon.eol.IEolModule;
import org.eclipse.epsilon.eol.launch.EolRunConfiguration;
import org.eclipse.epsilon.eol.launch.IEolRunConfiguration;

/**
 * A default config getter which effectively allows main method inheritance.
 * Uses reflection to find appropriate constructors and module interface to pass to parseModule method.
 * Please note: The constructors of this class must be inherited in R!
 * <br/>
 * Note that this needn't be subclassed to use it,
 * you can just add the required projects to the classpath
 * and call it with appropriate arguments, but you must provide
 * a module with the -module option.
 * 
 * @author Sina Madani
 * @since 1.6
 */
public class EolConfigParser<C extends IEolRunConfiguration, B extends IEolRunConfiguration.Builder<C, B>> extends ConfigParser<C, B> {

	/**
	 * Allows the caller to invoke any subclass of IEolModule.
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void main(String... args) throws ClassNotFoundException {
		if (args.length > 0) {
			
			if (args[0].toUpperCase().startsWith("CONFIG")) {
				Class<? extends IEolRunConfiguration> configClass = (Class<? extends IEolRunConfiguration>)
					Class.forName(args[0].substring(7));
				
				String[] adjustedArgs = Arrays.copyOfRange(args, 1, args.length);
				new EolConfigParser(IEolRunConfiguration.Builder(configClass)).apply(adjustedArgs).run();
			}
			else {
				new EolConfigParser(IEolRunConfiguration.Builder(getRunConfigurationForScript(args[0])))
					.apply(args).run();
			}
			
		}
	}
	
	private final String
		moduleOpt = "module",
		modelsOpt = "models",
		scriptParamsOpt = "parameters";
	
	
	public EolConfigParser(B builder) {
		super(builder);
		
		requiredUsage += "-models [model class]#[model properties];"+nL;
		optionalUsage += "  [module] [argtype=argvalue]s..."+nL;
		
		options.addOption(Option.builder(moduleOpt)
			.hasArg()
			.desc("Specify the module and arguments to the module in key-value pairs. "
				+ "Please note: the arguments type must be a fully qualified class and the class must have a String constructor"
				+ "which is used to parse the provided argument."
			)
			.optionalArg(false)
			.hasArgs()
			.valueSeparator()
			.build()
		);
		
		options.addOption(Option.builder(modelsOpt)
			.hasArgs()
			.desc("Specify the models and properties. The format first specifies the concrete Java class to"
				+ "be instantiated (fully qualified name after org.eclipse.epsilon.emc.), followed by #,"
				+ "followed by comma-separated key=value properties. For example: "
				+ "emf.EmfModel#name=modelName,cached=true;plainxml.PlainXmlModel#name=model2. "
				+ "This example specifies an EMF and a PlainXML model with their names as properties."
			)
			.valueSeparator(';')
			.build()
		);
		
		options.addOption(Option.builder(scriptParamsOpt)
			.hasArgs()
			.desc("Specify parameters to the script in comma-separated key=value pairs. Note that "
				+ "the type of variable passed will always be a String."
			)
			.optionalArg(true)
			.valueSeparator(',')
			.build()
		);
	}
	
	@Override
	protected void parseArgs(String[] args) throws Exception {
		super.parseArgs(args);
		
		if (cmdLine.hasOption(moduleOpt)) {
			builder.module = parseModule(cmdLine.getOptionValues(moduleOpt));
		}
		
		if (cmdLine.hasOption(modelsOpt)) {
			builder.modelsAndProperties.putAll(parseModelParameters(cmdLine.getOptionValues(modelsOpt)));
		}
		
		if (cmdLine.hasOption(scriptParamsOpt)) {
			builder.parameters.putAll(parseScriptParameters(cmdLine.getOptionValues(scriptParamsOpt)));
		}
	}
	
	public static Map<IModel, StringProperties> parseModelParameters(String[] arguments) throws Exception {
		Map<IModel, StringProperties> modelMap = new HashMap<>(arguments.length);
		
		for (String arg : arguments) {
			String[] modelPropertyEntry = arg.split("#");
			if (modelPropertyEntry.length != 2)
				continue;
			
			IModel model = (IModel) Class.forName("org.eclipse.epsilon.emc."+modelPropertyEntry[0])
				.getDeclaredConstructor()
				.newInstance();
			
			StringProperties properties = new StringProperties();
			for (String propertyToken : modelPropertyEntry[1].split(",")) {
				String[] propEntry = propertyToken.split("=");
				assert propEntry.length == 2;
				properties.put(propEntry[0], propEntry[1]);
			}
			
			modelMap.put(model, properties);
		}

		return modelMap;
	}
	
	public static Map<String, Object> parseScriptParameters(String[] arguments) {
		return Arrays.stream(arguments)
			.map(param -> {
				String[] entry = param.split("=");
				String key, value;
				
				if (entry.length != 2) {
					key = ""; value = "";
				}
				else {
					key = entry[0]; value = entry[1];
				}
				
				return new AbstractMap.SimpleEntry<>(key, value);
			})
			.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
	}
	
	/**
	 * Attempts to parse a module from command-line arguments, based on assumptions on Epsilon's conventional naming schemes and package structure.
	 * The names are based on the class name of the return type; so for example for IEolModule, it will use "ERL" as the language and look
	 * for the appropriate modules and contexts based on this name.
	 * 
	 * @param args the name of the module (following org.eclipse.epsilon.) followed by an even-arity array with arguments to provide to the context constructor,
	 * where every even numbered argument (including 0) is the class (type) and every odd numbered argument is the value.
	 * Note: only types with a String constructor are valid.
	 */
	@SuppressWarnings("unchecked")
	protected static <R extends IEolModule> R parseModule(String[] args) throws IllegalArgumentException {
		String basePkg = "org.eclipse.epsilon.";
		try {
			if (args.length == 0)
				throw new IllegalArgumentException("Must provide a module name.");
			int additionals = args.length-1;
			if (additionals % 2 != 0)
				throw new IllegalArgumentException("Must provide the types and arguments for module.");
			int arrSize = additionals/2;
			Class<?>[] moduleArgTypes = new Class[arrSize];
			Object[] parsedArgs = new Object[arrSize];
			
			for (int l = 0, a = 0; l < arrSize*2; l += 2, a++) {
				Class<?>[] type = getType(args[l+1]);
				Class<?> constructType = type.length == 2 ? type[1] : type[0];
				moduleArgTypes[a] = type[0];
				parsedArgs[a] = constructType.getConstructor(String.class).newInstance(args[l+2]);
			}

			Class<?> moduleClass = Class.forName(basePkg+args[0]);

			try {
				return (R) moduleClass.getDeclaredConstructor(moduleArgTypes).newInstance(parsedArgs);
			}
			catch (IllegalAccessException ex) {
				System.err.println("WARNING: Could not find appropriate constructor for supplied parameters. Proceeding with defaults.");
				System.err.println(ex.getMessage());
				return (R) moduleClass.getConstructor().newInstance();
			}
		}
		catch (Exception ex) {
			throw new IllegalArgumentException("Could not find or instantiate the module: "+ex.getMessage());
		}
	}
	
	@SuppressWarnings("unchecked")
	static Class<? extends IEolRunConfiguration> getRunConfigurationForScript(String scriptPath) {
		String ext = FileUtil.getExtension(scriptPath).toLowerCase();
		String pkg = ext.equals("egx") ? "egl" : ext;
		String className = "org.eclipse.epsilon."+pkg+".launch."+StringUtil.firstToUpper(ext)+"RunConfiguration";
		
		try {
			return (Class<? extends IEolRunConfiguration>) Class.forName(className);
		}
		catch (ClassNotFoundException cnfx) {
			return EolRunConfiguration.class;
		}
	}
	
	private static Class<?>[] getType(String specifiedType) throws ClassNotFoundException {
		final String pkg = "java.lang.";
		switch (specifiedType) {
			case "int": case "Integer": case pkg+"Integer":
				return new Class[]{Integer.TYPE, Integer.class};
			case "boolean": case "bool": case "Boolean": case pkg+"Boolean":
				return new Class[]{Boolean.TYPE, Boolean.class};
			case "double": case "Double": case pkg+"Double":
				return new Class[]{Double.TYPE, Double.class};
			case "float": case "Float": case pkg+"Float":
				return new Class[]{Float.TYPE, Float.class};
			case "long": case "Long": case pkg+"Long":
				return new Class[]{Long.TYPE, Long.class};
			case "byte": case "Byte": case pkg+"Byte":
				return new Class[]{Byte.TYPE, Byte.class};
			case "char": case "Character": case pkg+"Character":
				return new Class[]{Character.TYPE, Character.class};
			case "String": case "string": case pkg+"String":
				return new Class[]{String.class};
			default:
				return new Class[]{Class.forName(specifiedType)};
		}
	}
}