package eu.dnetlib.efg1914.various.servlet;

import java.io.IOException;
import java.io.InputStream;
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.various.utils.SetLocalesVariables;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import eu.dnetlib.efg1914.authoring.components.dao.ConfigurationDAO;
import eu.dnetlib.efg1914.authoring.components.dao.ThemeDAO;
import eu.dnetlib.efg1914.various.managers.PageCreator;
import eu.dnetlib.efg1914.various.managers.components.MainPage;

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

    private ApplicationContext context = null;
    private Transformer transformer = null;
    private ThemeDAO themeDao = null;
    private ConfigurationDAO configurationDao = null;
    private String sourcePath = null;

    //The name of the stored configuration xml file
    private String configurationName = null;

    //The String containing the name of the file that contains the code for statistics
    private String trackingFileName = null;
    private String trackingFileContent = null;
    private InputStream is = null;
    private String locale = null;
    private String locale2 = null;

    private String showLanguages = null;

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

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        setThemeDao((ThemeDAO) context.getBean("themeDao"));
        setConfigurationDao((ConfigurationDAO) context.getBean("configurationDao"));
        setSourcePath((String) context.getBean("gridfsPath"));
        setTrackingFileName((String) context.getBean("trackingFileName"));
        setConfigurationName((String) context.getBean("configurationName"));
        setLocale((String) context.getBean("locale"));
        setLocale2((String) context.getBean("locale2"));
        is = this.getClass().getClassLoader().getResourceAsStream(trackingFileName);

        try {
            if (is != null) {
                trackingFileContent = IOUtils.toString(is);
                is.close();
            } else {
                trackingFileContent = "";
            }


        } catch (IOException e) {
            logger.warn("Could not load tracking file.", e);

        }
        setShowLanguages((String) context.getBean("showLanguages"));

        if (!(showLanguages.equals("true") || showLanguages.equals("false"))) {
            showLanguages = "false";
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        PrintWriter writer = null;

        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        VelocityContext context = null;
        String selectedLanguage = request.getParameter("lan");
        if (selectedLanguage != null && !selectedLanguage.isEmpty() && (selectedLanguage.equals("el_GR") || selectedLanguage.equals("en_US"))) {
            request.getSession().setAttribute("language", selectedLanguage);
        }
        String lan = (String) request.getSession().getAttribute("language");
        if (lan == null || lan.isEmpty()) {
            request.getSession().setAttribute("language", locale);
            lan = (String) request.getSession().getAttribute("language");
        }
        try {
            MainPage mainPage = PageCreator.createMainPage(configurationDao, themeDao, configurationName, lan);

            Template t = ve.getTemplate("/eu/dnetlib/efg1914/various/servlet/menu.vm");
            StringWriter menuWriter = new StringWriter();
            context = new VelocityContext();
            context.put("current", "0");
            context.put("sourcePath", sourcePath);
            context.put("trackingCode", trackingFileContent);
//             try {
//                MyLocale myLocale= new MyLocale(lan);
//                context.put("home",  myLocale.getValue("menu.home"));
//                context.put("chronology", myLocale.getValue("menu.chronology"));
//                context.put("credits", myLocale.getValue("menu.credits"));
//                context.put("tooltip", myLocale.getValue("menu.tooltip"));
//                 context.put("language",  lan);
//                 context.put("languageText",  myLocale.getLanguage());
//                 context.put("showLanguages", showLanguages);
//             } catch (IOException e) {
//                e.printStackTrace();
//            }

            SetLocalesVariables.setContextVariables(context, lan, locale, locale2, showLanguages);

            t.merge(context, menuWriter);

            transformer = TransformerFactory.newInstance().newTemplates(new StreamSource(this.getClass().getClassLoader().getResourceAsStream("/eu/dnetlib/efg1914/various/servlet/mainPage.xsl"))).newTransformer();
            transformer.setParameter("sourcePath", sourcePath);
            transformer.setParameter("trackingCode", trackingFileContent);

            //add menu in transformer
            transformer.setParameter("menu", menuWriter.toString());

            //load screen warning page
            StringWriter warningWriter = new StringWriter();
            IOUtils.copy(this.getClass().getClassLoader().getResourceAsStream("/eu/dnetlib/efg1914/various/servlet/screenSizeWarning.html"), warningWriter);

            //add screen warning in transformer
            transformer.setParameter("screenSizeWarning", warningWriter.toString());
            transformer.setParameter("requestPath", request.getRequestURL().substring(0, request.getRequestURL().length() - request.getServletPath().length()));
            transformer.setParameter("requestUrl", request.getRequestURL());

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

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

            response.setCharacterEncoding("UTF-8");
            writer = response.getWriter();
            transformer.transform(new StreamSource(new StringReader(stringWriter.toString())), new StreamResult(writer));
            logger.debug("main page xml" + stringWriter.toString());

        } catch (Exception e) {
            logger.error("Fail to load main page", e);
        }
    }

    public String getLocale2() {
        return locale2;
    }

    public void setLocale2(String locale2) {
        this.locale2 = locale2;
    }

    public String getShowLanguages() {
        return showLanguages;
    }

    public void setShowLanguages(String showLanguages) {
        this.showLanguages = showLanguages;
    }

    public ThemeDAO getThemeDao() {
        return themeDao;
    }

    public void setThemeDao(ThemeDAO themeDao) {
        this.themeDao = themeDao;
    }

    public String getSourcePath() {
        return sourcePath;
    }

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

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

    public String getTrackingFileName() {
        return trackingFileName;
    }

    public void setTrackingFileName(String trackingFileName) {
        this.trackingFileName = trackingFileName;
    }

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