package eu.dnetlib.goldoa.service;

import eu.dnetlib.goldoa.domain.Currency;
import org.w3c.dom.Document;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by antleb on 5/4/15.
 */
public class CurrencyConverter {

	private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
	private Map<Currency, Float> rateMap = new HashMap<Currency, Float>();

	@PostConstruct
	public void init() throws XPathExpressionException, ParserConfigurationException {
		executorService.scheduleAtFixedRate(new RateUpdater(), 0, 1, TimeUnit.HOURS);
	}

	@PreDestroy
	public void destroy() {
		executorService.shutdownNow();
	}

	public float convert(Currency from, Currency to, float amount) {
		float fromRate = rateMap.get(from);
		float toRate = rateMap.get(to);

		return (toRate / fromRate) * amount;
	}

	class RateUpdater implements Runnable {

		private Map<Currency, XPathExpression> xpaths = new HashMap<Currency, XPathExpression>();
		DocumentBuilder builder;

		public RateUpdater() throws ParserConfigurationException, XPathExpressionException {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			builder = factory.newDocumentBuilder();

			XPathFactory xPathfactory = XPathFactory.newInstance();
			XPath xpath = xPathfactory.newXPath();

			for (Currency currency : Currency.values())
				if (!currency.equals(Currency.EUR))
					xpaths.put(currency, xpath.compile("//*[local-name()='Cube' and @*[local-name()='currency']='" + currency.name() + "']/@rate"));
		}

		@Override
		public void run() {
			try {
				Document doc = builder.parse("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");

				rateMap.put(Currency.EUR, 1.0f);

				for (Currency currency : xpaths.keySet()) {
					String rate = xpaths.get(currency).evaluate(doc);

					if (rate != null)
						rateMap.put(currency, Float.parseFloat(rate));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
