/*
 * Copyright (C) 2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 *
 * This file is part of WSDDE.
 *
 * WSDDE is free software: it may be distributed and/or modified under
 * the terms of the GNU General Public License version 3 as published
 * by the Free Software Foundation and appearing in the file doc/gpl.txt
 * included in the packaging of this file.
 *
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

package wsdde;

import java.io.StringWriter;
import java.lang.Thread.State;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import wsdde.general.DatabaseHelper;
import wsdde.general.Utils;

public class WSDExperiment extends Vector<WSDMethod> {
	
	private int max_time;
	private int max_memory;
	
	public boolean saveModels = true;
	
	Document doc;
	public boolean toDB = false;
	
	DatabaseHelper dbh;
	
	public WSDExperiment(String xml_description_file) {//jak zrobic 
		try {
			DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
	
			doc = docBuilder.parse(xml_description_file);
			
			/*
			XPathFactory factory = XPathFactory.newInstance();
		    XPath xpath = factory.newXPath();
		    XPathExpression expr 
		     = xpath.compile("//feature_generator[@name='wsdde.generator.SFG1']/param[@name='lemmatisation']/@value");

		    Object result2 = expr.evaluate(doc, XPathConstants.NODESET);
		    NodeList nodes = (NodeList) result2;
		    for (int i = 0; i < nodes.getLength(); i++) {
		        System.out.println(nodes.item(i).getNodeValue()); 
		    }	
			System.exit(0);
*/			
			//weka.classifiers.bayes.NaiveBayes
			//get general settings
				//max_time, etc.
			//weka.classifiers.bayes.BayesNet -D -Q weka.classifiers.bayes.net.search.local.K2 -- -P 1 -S BAYES -E weka.classifiers.bayes.net.estimate.SimpleEstimator -- -A 0.5
			//get WSD method details
			
			//DatabaseHelper.init((Element)doc.getElementsByTagName("wsd_experiment").item(0));
			
			NodeList wsd_methods_list = doc.getElementsByTagName("wsd_method");
			
			for (int i=0; i<wsd_methods_list.getLength(); i++) {
				Element wsd_method_element = (Element)wsd_methods_list.item(i);
				this.add(new WSDMethod(wsd_method_element,this));
			}
			
		} catch (Exception e) {
			System.err.print("XML experiment description, parse error");
			e.printStackTrace();
		} 
		
	}
	
	public void writeToDB(boolean write) {
		if (write) {
			toDB = write;
			dbh = new DatabaseHelper((Element)doc.getElementsByTagName("wsd_experiment").item(0));
			dbh.createTable();
			for (WSDMethod wsdm : this) {
				wsdm.initDBRow();
			}
		}
	}
	
	public String conduct() {
		for (WSDMethod wsd_method : this) {
			wsd_method.loadCorpora();
			int time = wsd_method.maxExecutionTimeMs;
			wsd_method.setSaveModels(saveModels);
			Thread t = new Thread(wsd_method);
			//System.out.println("start...");
			t.start();
			try {
				t.join(time);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (t.getState()==State.RUNNABLE) {
				System.out.println("timeout");
				t.stop(); //GRRRRRRRRRRRRRRR
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				wsd_method.cleanAfterStop();
			} else {
				//System.out.println("done");
			}
			wsd_method.pushOKData();
//			System.out.println(wsd_method);
//			System.out.println(wsd_method.results.detailedResults());
			
			//wsd_method.run();
		}
		
		//PRINT OUT XML
		try {		
			Transformer transformer = TransformerFactory.newInstance().newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
	
			//initialize StreamResult with File object to save to file
			StreamResult result = new StreamResult(new StringWriter());
			DOMSource source = new DOMSource(doc);
			transformer.transform(source, result);
	
			String xmlString = result.getWriter().toString();
			return xmlString;
		} catch (Exception e) {
			e.printStackTrace();
		} 
		
		return null;
		//for (WSDMethod wsd_method : this) {
			//System.out.println(wsd_method.results.detailedResults());
		//}
	}


	public static void main(String [] args) {
		//WSDExperiment myExp = new WSDExperiment("sing_experiment_description.xml");
		WSDExperiment myExp = new WSDExperiment("desc.xml");
		myExp.writeToDB(true);
		//System.out.println("end of parsing xml");
		myExp.conduct();
		
	}
	
}