package eu.dnetlib.efg1914.various.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import eu.dnetlib.efg1914.authoring.components.dao.*;
import eu.dnetlib.efg1914.various.locales.MyLocale;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import eu.dnetlib.efg1914.various.managers.PageCreator;
import eu.dnetlib.efg1914.various.managers.components.FramePage;

@SuppressWarnings("serial")
public class FramePageServlet extends HttpServlet {

    private ApplicationContext context = null;
    private Transformer transformer = null;
    private ThemeDAO themeDAO = null;
    private TopicDAO topicDAO = null;
    private FrameDAO frameDao = null;
    private ItemDAO itemDao = null;
    private ConfigurationDAO configurationDao=null;
    private String configurationName = null;
    private String sourcePath = null;
    private String locale = null;


    private static Logger logger = Logger.getLogger(FramePageServlet.class);

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        setItemDao((ItemDAO) context.getBean("itemDao"));
        setFrameDao((FrameDAO) context.getBean("frameDao"));
        setTopicDAO((TopicDAO) context.getBean("topicDao"));
        setThemeDAO((ThemeDAO) context.getBean("themeDao"));
        setConfigurationDao((ConfigurationDAO) context.getBean("configurationDao"));
        setConfigurationName((String) context.getBean("configurationName"));

        setSourcePath((String) context.getBean("gridfsPath"));
        setLocale((String) context.getBean("locale"));

    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter writer = null;
        String id = request.getParameter("id");
        String themeId = request.getParameter("theme");
        String requester = request.getParameter("requester");
        String requestPath = request.getRequestURL().substring(0, request.getRequestURL().length() - request.getServletPath().length());
        if (id == null) {
            //TODO serve home page
            //throw new UnsupportedOperationException("Undefined action.");
        }
        String lan = (String) request.getSession().getAttribute("language");
        if (lan == null || lan.isEmpty()) {
            request.getSession().setAttribute("language", locale);
            lan = (String) request.getSession().getAttribute("language");
        }
        try {
            String socialLink = requestPath + "/frame?id=" + id + "&theme=" + themeId + "&requester=social";
            response.setCharacterEncoding("UTF-8");
            writer = response.getWriter();
            FramePage framePage = PageCreator.createFramePage(configurationDao,configurationName,themeDAO, topicDAO, frameDao, itemDao, id, themeId);

            JAXBContext jaxbcontext = JAXBContext.newInstance(FramePage.class);
            Marshaller marshaller = jaxbcontext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

            StringWriter stringWriter = new StringWriter();
            marshaller.marshal(framePage, stringWriter);

            logger.debug("framePage: " + stringWriter.toString());

            transformer = TransformerFactory.newInstance().newTemplates(new StreamSource(this.getClass().getClassLoader().getResourceAsStream("/eu/dnetlib/efg1914/various/servlet/frame.xsl"))).newTransformer();
            transformer.setParameter("gridfsPath", sourcePath);
            transformer.setParameter("socialLink", socialLink);
            if (requester == null || requester.trim() == "") {
                transformer.setParameter("requester", "");
            } else {
                transformer.setParameter("requester", requester);
            }

            transformer.setParameter("requestPath", requestPath);
            String queryString = request.getQueryString();
            if (queryString == null) {
                transformer.setParameter("requestUrl", request.getRequestURL());
            } else {
                transformer.setParameter("requestUrl", request.getRequestURL().append('?').append(queryString).toString());
            }
            try {
                MyLocale myLocale = new MyLocale(lan);
                transformer.setParameter("providedBy", myLocale.getValue("frame.providedBy"));
                transformer.setParameter("viewOn", myLocale.getValue("frame.viewOn"));
                transformer.setParameter("viewFilmOn", myLocale.getValue("frame.viewFilmOn"));
                transformer.setParameter("related", myLocale.getValue("frame.related"));

            } catch (IOException e) {
                e.printStackTrace();
            }

            transformer.transform(new StreamSource(new StringReader(stringWriter.toString())), new StreamResult(writer));

        } catch (Exception e) {
            logger.error("Fail to load frame page for frame " + id, e);
        }

    }


    public void setLocale(String locale) {
        this.locale = locale;
    }

    public FrameDAO getFrameDao() {
        return frameDao;
    }

    public void setFrameDao(FrameDAO frameDao) {
        this.frameDao = frameDao;
    }

    public ItemDAO getItemDao() {
        return itemDao;
    }

    public void setItemDao(ItemDAO itemDao) {
        this.itemDao = itemDao;
    }

    public String getSourcePath() {
        return sourcePath;
    }

    public void setSourcePath(String sourcePath) {
        this.sourcePath = sourcePath;
    }

    public ThemeDAO getThemeDAO() {
        return themeDAO;
    }

    public void setThemeDAO(ThemeDAO themeDAO) {
        this.themeDAO = themeDAO;
    }

    public TopicDAO getTopicDAO() {
        return topicDAO;
    }

    public void setTopicDAO(TopicDAO topicDAO) {
        this.topicDAO = topicDAO;
    }

    public ConfigurationDAO getConfigurationDao() {
        return configurationDao;
    }

    public void setConfigurationDao(ConfigurationDAO configurationDao) {
        this.configurationDao = configurationDao;
    }
    public String getConfigurationName() {
        return configurationName;
    }

    public void setConfigurationName(String configurationName) {
        this.configurationName = configurationName;
    }

}
