package ru.yandex.wmtools.common.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import com.Ostermiller.util.CircularCharBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.InternalProblem;

/**
 * @author senin
 * @author ailyin
 */
public class XSLTXmlSearchResultParser implements XmlSearchResultParser<Reader> {
    private static final Logger log = LoggerFactory.getLogger(XSLTXmlSearchResultParser.class);

    private final String xslFileName;

    public XSLTXmlSearchResultParser(String xslFileName) {
        this.xslFileName = xslFileName;
    }

    @Override
    public Reader parseResult(Reader queryResult) throws InternalException {
        log.debug("parseResult() started");
        InputStream xslStream = getClass().getResourceAsStream(xslFileName);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        try {
            Templates stylesheet = transformerFactory.newTemplates(new StreamSource(xslStream));
            Transformer processor = stylesheet.newTransformer();

            CircularCharBuffer ocbb = new CircularCharBuffer(CircularCharBuffer.INFINITE_SIZE);
            StreamResult result = new StreamResult(ocbb.getWriter());

            processor.transform(new StreamSource(queryResult), result);
            ocbb.getWriter().close();

            log.debug("parseResult() finished");
            return ocbb.getReader();
        } catch (TransformerConfigurationException e) {
            throw new InternalException(InternalProblem.PROCESSING_ERROR,
                    "TransformerConfigurationException in XSLTXmlSearchResultParser!", e);
        } catch (TransformerException e) {
            throw new InternalException(InternalProblem.PROCESSING_ERROR,
                    "TransformerException in XSLTXmlSearchResultParser!", e);
        } catch (IOException e) {
            throw new InternalException(InternalProblem.PROCESSING_ERROR,
                    "IOException in XSLTXmlSearchResultParser!", e);
        }
    }
}
