package org.minimalj.frontend.impl.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Locale;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.minimalj.application.Application;
import org.minimalj.frontend.Frontend;
import org.minimalj.frontend.impl.json.JsonFrontend;
import org.minimalj.util.StringUtils;
import org.minimalj.util.resources.Resources;

public class MjServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger(MjServlet.class.getName());
	
	private static boolean applicationInitialized;
	
	protected void initializeApplication() {
		if (!applicationInitialized) {
			Frontend.setInstance(new JsonFrontend());
			String applicationName = getServletConfig().getInitParameter("Application");
			if (StringUtils.isBlank(applicationName)) {
				throw new IllegalArgumentException("Missing Application parameter");
			}
			copyPropertiesFromServletConfigToSystem();
			Application application = Application.createApplication(applicationName);
			Application.setApplication(application);
			applicationInitialized = true;
		}
	}
	
	private void copyPropertiesFromServletConfigToSystem() {
		Enumeration<?> propertyNames = getServletConfig().getInitParameterNames();
		while (propertyNames.hasMoreElements()) {
			String propertyName = (String) propertyNames.nextElement();
			System.setProperty(propertyName, getServletConfig().getInitParameter(propertyName));
		}
	}	
	
	@Override
	public void init() throws ServletException {
		initializeApplication();
	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String contextPath = request.getContextPath();
		String requestURI = request.getRequestURI();
		String uri = requestURI.substring(contextPath.length());

		InputStream inputStream = null;
		if (uri.equals("")) {
			response.sendRedirect("./");
			return;
		} else if (uri.equals("/")) {
			String htmlTemplate = JsonFrontend.getHtmlTemplate();
			String html = fillPlaceHolder(htmlTemplate, request.getLocale(), request.getRequestURL().toString());
			response.getWriter().write(html);
			response.setContentType("text/html");
			return; // !
		} else {
			int index = uri.lastIndexOf('.');
			if (index > -1 && index < uri.length()-1) {
				String postfix = uri.substring(index+1);
				String mimeType = Resources.getMimeType(postfix);
				if (mimeType != null) {
					response.setContentType(mimeType);
					inputStream = Resources.getInputStream(uri.substring(1));
				}
			}
		}
		if (inputStream == null) {
			logger.warning("Could not serve: " + uri);
			response.setStatus(403);
			return;
		}
		
		OutputStream outputStream = response.getOutputStream();
		byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, length);
        }
	}
	
	protected String fillPlaceHolder(String html, Locale locale, String url) {
		// gives a subclass to replace some texts in the index.html
		return JsonFrontend.fillPlaceHolder(html, locale);
	}
}
@@ -210,16 +210,52 @@
 .Logger;
+%0Aimport java.util.stream.Collectors;
 %0A%0Aimport
@@ -549,32 +549,84 @@
 n.JsonFrontend;%0A
+import org.minimalj.frontend.impl.json.JsonHandler;%0A
 import org.minim
@@ -874,16 +874,16 @@
 e());%0A%09%0A
-
 %09private
@@ -924,16 +924,68 @@
 ized;%0A%09%0A
+%09private JsonHandler handler = new JsonHandler();%0A%09%0A
 %09protect
@@ -2614,13 +2614,294 @@
 urn;
- // !
+%0A%09%09%7D else if (%22/ajax_request.xml%22.equals(uri)) %7B%0A%09%09%09String postData = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));%0A%09%09%09String result = handler.handle(postData);%0A%09%09%09response.getWriter().write(result);%0A%09%09%09response.setContentType(%22text/xml%22);%0A%09%09%09return;%09
 %0A%09%09%7D

support ajax communication