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.ConfigurationDAO;
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.authoring.components.dao.ItemDAO;
import eu.dnetlib.efg1914.authoring.components.dao.ThemeDAO;
import eu.dnetlib.efg1914.various.managers.PageCreator;
import eu.dnetlib.efg1914.various.managers.components.ItemPage;

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

    private ApplicationContext context = null;
    private Transformer transformer = null;

    private String sourcePath = null;

    private ItemDAO itemDao = null;
    private ThemeDAO themeDao = null;
    private ConfigurationDAO configurationDao = null;
    private String configurationName = null;

    private static Logger logger = Logger.getLogger(ItemPageServlet.class);
    private String locale = null;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        setSourcePath((String) context.getBean("gridfsPath"));
        setItemDao((ItemDAO) context.getBean("itemDao"));
        setThemeDao((ThemeDAO) context.getBean("themeDao"));
        setConfigurationDao((ConfigurationDAO) context.getBean("configurationDao"));
        setConfigurationName((String) context.getBean("configurationName"));
        setLocale((String) context.getBean("locale"));

    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter writer = null;
        String id = request.getParameter("id");
        String requester = request.getParameter("requester");
        String requestPath = request.getRequestURL().substring(0, request.getRequestURL().length() - request.getServletPath().length());
        String socialLink = requestPath + "/item?id=" + id + "&requester=social";
        String lan = (String) request.getSession().getAttribute("language");
        if (lan == null || lan.isEmpty()) {
            request.getSession().setAttribute("language", locale);
            lan = (String) request.getSession().getAttribute("language");
        }
        logger.debug("Request for " + id + " item");

        if (id == null) {
            //TODO serve home page
            //throw new UnsupportedOperationException("Undefined action.");
        }


        try {
            transformer = TransformerFactory.newInstance().newTemplates(new StreamSource(this.getClass().getClassLoader().getResourceAsStream("/eu/dnetlib/efg1914/various/servlet/item.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("item.providedBy"));
                transformer.setParameter("viewOn", myLocale.getValue("item.viewOn"));
                transformer.setParameter("viewFilmOn", myLocale.getValue("item.viewFilmOn"));
                transformer.setParameter("found", myLocale.getValue("item.found"));

            } catch (IOException e) {
                e.printStackTrace();
            }
            ItemPage itemPage = null;
            if (requester == null || requester.trim() == "") {
                itemPage = PageCreator.createItemPage(configurationDao,configurationName,itemDao, themeDao, id, true);
            } else {
                itemPage = PageCreator.createItemPage(configurationDao,configurationName,itemDao, themeDao, id, false);
            }

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

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

            response.setCharacterEncoding("UTF-8");
            writer = response.getWriter();

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

            logger.debug("ITEM PAGE: " + stringWriter.toString());

        } catch (Exception e) {
            logger.error("Fail to load item", e);
            //TODO do a redirect or something
        }

    }

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

    public String getSourcePath() {
        return sourcePath;
    }

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

    public ItemDAO getItemDao() {
        return itemDao;
    }

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

    public ThemeDAO getThemeDao() {
        return themeDao;
    }

    public void setThemeDao(ThemeDAO themeDao) {
        this.themeDao = themeDao;
    }
    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;
    }
}
