package net.psammead.commonist.text;

import java.io.*;
import java.net.*;
import java.util.*;

import net.psammead.commonist.util.*;
import net.psammead.minibpp.Compiler;
import net.psammead.util.*;
import bsh.*;

/** compiles image metadata into a [[Template:Information]] for commons or something similar for other wikis */
public class Templates {
	private static final Logger log = new Logger(Templates.class);

	private static final String	TEMPLATE_ENCODING	= "UTF-8";
	
	private Loader	loader;
	
	public Templates(Loader loader) {
		this.loader	= loader;
	}
	
	public String applyTemplate(String templatePath, Map<String,?> data) throws TemplateException {
		// TODO: use mandatoryURL
		URL	url	= loader.optionalURL(templatePath);
		if (url == null)	throw new TemplateException("unknown template: " + templatePath);
		
		Reader	tin	= null;
		Reader	cin	= null;
		try {
			tin	= new InputStreamReader(
					url.openConnection().getInputStream(), 
					TEMPLATE_ENCODING);
			Compiler	compiler	= new Compiler();
			String		code		= compiler.compile(tin);


			StringWriter	sout	= new StringWriter();
			PrintWriter		xout	= new PrintWriter(sout);
			
			Interpreter	interpreter	= new Interpreter();
			interpreter.set("out",	xout);
			for (Iterator<String> it=data.keySet().iterator(); it.hasNext();) {
				String	key		= it.next();
				Object	value	= data.get(key);
				interpreter.set(key, value);
			}

			cin	= new StringReader(code);
			interpreter.eval(cin, interpreter.getNameSpace(), url.toExternalForm());
			
			return sout.toString();
		}
		catch (Exception e) {
			log.error("cannot use template: " + url.toExternalForm(), e);
			throw new TemplateException("cannot use template: " + url.toExternalForm(), e);
		}
		finally {
			if (tin != null)
				try { tin.close(); }
				catch (Exception e) { log.error("cannot close template stream", e); }
			if (cin != null)
				try { cin.close(); }
				catch (Exception e) { log.error("cannot close template stream", e); }
		}
	}
}
