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();
            }
        }
    }
}
