package multeval;

import jannopts.ConfigurationException;
import jannopts.Configurator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import multeval.metrics.BLEU;
import multeval.metrics.Length;
import multeval.metrics.Metric;
import multeval.metrics.TER;

import com.google.common.collect.ImmutableMap;

public class MultEval {

	// case sensitivity option? both? use punctuation?
	// report length!

	public static Map<String, Metric<?>> KNOWN_METRICS = ImmutableMap.<String, Metric<?>> builder()
			.put("bleu", new BLEU())
			.put("meteor", new multeval.metrics.METEOR())
			.put("ter", new TER())
			.put("length", new Length())
			.build();

	static List<Metric<?>> loadMetrics(String[] metricNames, Configurator opts)
			throws ConfigurationException {

		// 1) activate config options so that we fail-fast
		List<Metric<?>> metrics = new ArrayList<Metric<?>>();
		for (String metricName : metricNames) {
			System.err.println("Loading metric: " + metricName);
			Metric<?> metric = KNOWN_METRICS.get(metricName.toLowerCase());
			if (metric == null) {
				throw new RuntimeException("Unknown metric: " + metricName
						+ "; Known metrics are: " + KNOWN_METRICS.keySet());
			}

			// add metric options on-the-fly as needed
			opts.activateDynamicOptions(metric.getClass());

			metrics.add(metric);
		}

		// 2) load metric resources, etc.
		for (Metric<?> metric : metrics) {
			metric.configure(opts);
		}

		return metrics;
	}

	private static final ImmutableMap<String, Module> MODULES =
			new ImmutableMap.Builder<String, Module>().put("eval", new MultEvalModule())
					.put("nbest", new NbestModule())
					.build();

	static int initThreads(final List<Metric<?>> metrics, int threads) {

		if (threads == 0) {
			threads = Runtime.getRuntime().availableProcessors();
		}
		System.err.println("Using " + threads + " threads");
		return threads;
	}

	public static void main(String[] args) throws ConfigurationException, IOException,
			InterruptedException {

		if (args.length == 0 || !MODULES.keySet().contains(args[0])) {
			System.err.println("Usage: program <module_name> <module_options>");
			System.err.println("Available modules: " + MODULES.keySet().toString());
			System.exit(1);
		} else {
			String moduleName = args[0];
			Module module = MODULES.get(moduleName);
                        // TODO: Load version from constants file
			Configurator opts =
					new Configurator().withProgramHeader(
							"MultEval V0.5.0\nBy Jonathan Clark\nUsing Libraries: METEOR (Michael Denkowski) and TER (Matthew Snover)\n")
							.withModuleOptions(moduleName, module.getClass());

			// add "dynamic" options, which might be activated later
			// by the specified switch values
			for (Class<?> c : module.getDynamicConfigurables()) {
				opts.allowDynamicOptions(c);
			}

			try {
				opts.readFrom(args);
				opts.configure(module);
			} catch (ConfigurationException e) {

				opts.printUsageTo(System.err);
				System.err.println("ERROR: " + e.getMessage() + "\n");
				System.exit(1);
			}

			module.run(opts);
		}
	}
}

@@ -103,32 +103,93 @@
 io.IOException;%0A
+import java.io.FileInputStream;%0Aimport java.util.Properties;%0A
 import java.util
@@ -1985,117 +1985,728 @@
 %09%7D%0A%0A
-%09public static void main(String%5B%5D args) throws ConfigurationException, IOException,%0A%09%09%09InterruptedException %7B
+        private static String loadVersion() throws IOException %7B%0A            Properties props = new Properties();%0A            FileInputStream in = new FileInputStream(%22constants%22);%0A            props.load(in);%0A            in.close();%0A            String version = props.getProperty(%22version%22);%0A            return version;%0A        %7D%0A%0A%09public static void main(String%5B%5D args) throws ConfigurationException, IOException,%0A%09%09%09InterruptedException %7B%0A%0A            String version = loadVersion();%0A            System.err.println(String.format(%22MultEval V%25s%5Cn%22, version) +%0A                               %22By Jonathan Clark%5Cn%22 +%0A                               %22Using Libraries: METEOR (Michael Denkowski) and TER (Matthew Snover)%5Cn%22);
 %0A%0A%09%09
@@ -3026,74 +3026,8 @@
 e);%0A
-                        // TODO: Load version from constants file%0A
 %09%09%09C
@@ -3044,22 +3044,17 @@
 r opts =
-%0A%09%09%09%09%09
+ 
 new Conf
@@ -3067,152 +3067,8 @@
 or()
-.withProgramHeader(%0A%09%09%09%09%09%09%09%22MultEval V0.5.0%5CnBy Jonathan Clark%5CnUsing Libraries: METEOR (Michael Denkowski) and TER (Matthew Snover)%5Cn%22)%0A%09%09%09%09%09%09%09
 .wit

Load version from file