package czsem.gate.utils;

import gate.Corpus;
import gate.Document;
import gate.Factory;
import gate.FeatureMap;
import gate.ProcessingResource;
import gate.creole.ExecutionException;
import gate.creole.ResourceInstantiationException;
import gate.creole.SerialAnalyserController;
import gate.util.GateException;

import java.util.Arrays;
import java.util.List;

import czsem.gate.plugins.LearningEvaluator;

public abstract class PRSetup
{
	public static class SinglePRSetup extends PRSetup 
	{
		private String pr_className;
		private FeatureMap fm;
		private String name = null;
	
		public SinglePRSetup(String className, String name)
		{
			pr_className = className;
			fm = Factory.newFeatureMap();
			this.name = name;
			
		}

		public SinglePRSetup(Class<?> cl, String name)
		{
			this(cl.getCanonicalName(), name);			
		}

		public SinglePRSetup(Class<?> cl)
		{
			this(cl, null);
		}

		public SinglePRSetup(String classneme)
		{
			this(classneme, null);
		}
				
		public SinglePRSetup putFeature(Object key, Object value)
		{
			fm.put(key, value);
			return this;
		}
		public SinglePRSetup putFeatureList(Object key, String ... strig_list)
		{
			if (strig_list == null)
				fm.put(key, null);
			else
				fm.put(key, Arrays.asList(strig_list));
			return this;
		}
	
		public ProcessingResource createPR() throws ResourceInstantiationException
		{
			return(ProcessingResource) Factory.createResource(pr_className, fm, null, name);			
		}				
	}
	
	public static class MLEvaluateSetup extends SinglePRSetup
	{

		private List<LearningEvaluator> evaluation_register;

		public MLEvaluateSetup(List<LearningEvaluator> evaluation_register)
		{
			super(LearningEvaluator.class);
			this.evaluation_register = evaluation_register;
		}

		@Override
		public ProcessingResource createPR() throws ResourceInstantiationException
		{
			ProcessingResource ret = super.createPR();
			evaluation_register.add((LearningEvaluator) ret);
			return ret;
		}

	}


	public abstract ProcessingResource createPR() throws ResourceInstantiationException;

	public static SerialAnalyserController buildGatePipeline(PRSetup [] prs, String name) throws ResourceInstantiationException	{
		return buildGatePipeline(Arrays.asList(prs), name);
	}

	public static void execGatePipeline(PRSetup [] prs, String name, String docContent) throws ResourceInstantiationException, ExecutionException {
		Document doc = Factory.newDocument(docContent);
		execGatePipeline(prs, name, doc);
		Factory.deleteResource(doc);
	}

	public static void execGatePipeline(PRSetup [] prs, String name, Document doc) throws ResourceInstantiationException, ExecutionException {
		SerialAnalyserController pipe = buildGatePipeline(Arrays.asList(prs), name);
		Corpus corpus = Factory.newCorpus("corpus_for_"+name);
		pipe.setCorpus(corpus);
		corpus.add(doc);
		pipe.execute();
		corpus.clear();
		Factory.deleteResource(corpus);
		GateUtils.deepDeleteController(pipe);
	}

	public static SerialAnalyserController buildGatePipeline(List<PRSetup> prs, String name) throws ResourceInstantiationException
	{
		try {
			GateUtils.registerComponentIfNot(NotCheckingParametersSerialController.class);
		} catch (GateException e1) {
			throw new ResourceInstantiationException(e1);
		}
		
		SerialAnalyserController controller = (SerialAnalyserController) Factory.createResource(
			NotCheckingParametersSerialController.class.getCanonicalName());
		
		controller.setName(name);
	
		
		for (int i = 0; i < prs.size(); i++)
		{
			try {
				controller.add(prs.get(i).createPR());
			} catch (ResourceInstantiationException e) {
				try {
					GateUtils.deepDeleteController(controller);
				} catch (Throwable t) {
					e.addSuppressed(t);
				}
				
				throw e;
			}
		}
				
		return controller;		
	}		
}
@@ -307,16 +307,76 @@
 ption;%0A%0A
+import java.net.MalformedURLException;%0Aimport java.net.URL;%0A
 import j
@@ -3139,102 +3139,347 @@
 %0A%09%09%09
-GateUtils.registerComponentIfNot(NotCheckingParametersSerialController.class);%0A%09%09%7D catch (Gate
+URL res = NotCheckingParametersSerialController.class.getResource(%0A%09%09%09%09%09%22/gate/creole/CreoleRegisterImpl.class%22);%0A%09%09%09%0A%09%09%09if (res != null)%0A%09%09%09%09GateUtils.registerComponentIfNot(NotCheckingParametersSerialController.class);%0A%09%09%09else %7B%0A%09%09%09%09GateUtils.registerPluginDirectory(%22czsem-gate-plugin%22);%0A%09%09%09%7D%0A%09%09%09%0A%09%09%7D catch (GateException %7C MalformedURL
 Exce

load czsem-gate-plugin if url for CreoleRegisterImpl is null