package com.hammurapi.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Map;

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

import org.onemind.commons.java.util.MapUtils;
import org.onemind.commons.java.util.ServletUtils;
import org.onemind.commons.java.util.StringUtils;
import org.onemind.jxp.JxpContext;
import org.onemind.jxp.JxpPageNotFoundException;
import org.onemind.jxp.JxpPageSourceException;
import org.onemind.jxp.JxpProcessor;

/**
 * Renders JXP files. OOTB JXP servlet does not work.
 */
public class JxpServlet extends HttpServlet {
	private static final long serialVersionUID = 2L;
	private JxpProcessor processor;
       
    /**
     * Get the processor
     * @param req the request
     * @return the processor
     * @throws Exception
     */
    private JxpProcessor getProcessor(HttpServletRequest req) throws Exception {
        if (processor == null) {
            synchronized (this) {                
                if (processor != null) {                    
                    return processor;
                }
                
                processor = new JxpProcessor(new JxpContext(new ServletContextResourceStreamPageSource(getServletContext())));
            }
        }
        return processor;
    }

    /**
     * {@inheritDoc}
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map env = ServletUtils.getServletEnvironment(getServletConfig());
        env.putAll(ServletUtils.getRequestEnvironment(req));
        env.putAll(ServletUtils.getExtraRequestEnvironment(req));        
//        Map form = new HashMap();
        
        String uri = req.getRequestURI();
        if (uri.endsWith("JxpServlet")) {
            dumpDebugInfo(req, resp, env);
        } else {
            resp.setContentType("text/html");
            resp.setStatus(200);
            Writer writer = resp.getWriter();
//            env.put("form", form);
            env.put("req", req);
            env.put("resp", resp);
            String uripath = StringUtils.substringBeforeLast(uri, "/");
            if (uripath == null) {
                uripath = "/";
            }
            env.put("uripath", uripath);
            try {
//                form.putAll(ServletUtils.getRequestParameters(req, _uploadRepository));
                JxpProcessor processor = getProcessor(req);
                if (uri.endsWith("/")) {
                	uri+="index.jxp";
                }
                processor.process(uri, writer, env);
            } catch (JxpPageNotFoundException pnfe) {
                getServletContext().log("Error processing uri" + uripath + ": " + pnfe.getMessage(), pnfe);
                writer.write(pnfe.getMessage());
            } catch (JxpPageSourceException jpse) {
            	getServletContext().log("Error processing uri" + uripath + ": " + jpse.getMessage(), jpse);
                writer.write(jpse.getMessage());
            } catch (Exception e) {
            	getServletContext().log("Error processing uri" + uripath, e);
                e.printStackTrace(new PrintWriter(writer));
            } finally {
                writer.flush();
            }
        }
    }

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	
    /**
     * Output the debugging information
     * @param req the request
     * @param resp the resoibse
     * @param env the environment
     * @throws IOException io exceptions
     */
    private void dumpDebugInfo(HttpServletRequest req, HttpServletResponse resp, Map env) throws IOException {
        resp.setContentType("text/html");
        resp.setStatus(200);
        PrintWriter output = resp.getWriter();
        output.write("<html><body><pre>");
        MapUtils.dump(env, output);
        output.write("</pre></body></html>");
        output.flush();
        output.close();
        return;
    }
	

}
