/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package groovy.servlet;

import groovy.lang.Binding;
import groovy.xml.MarkupBuilder;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.runtime.MethodClosure;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Servlet-specific binding extension to lazy load the writer or the output
 * stream from the response.
 * <p>
 * <h3>Eager variables</h3>
 * <ul>
 * <li><tt>"request"</tt> : the <code>HttpServletRequest</code> object</li>
 * <li><tt>"response"</tt> : the <code>HttpServletRequest</code> object</li>
 * <li><tt>"context"</tt> : the <code>ServletContext</code> object</li>
 * <li><tt>"application"</tt> : same as context</li>
 * <li><tt>"session"</tt> : shorthand for <code>request.getSession(<tt>false</tt>)</code> - can be null!</li>
 * <li><tt>"params"</tt> : map of all form parameters - can be empty</li>
 * <li><tt>"headers"</tt> : map of all <tt>request</tt> header fields</li>
 * </ul>
 * <p>
 * <h3>Lazy variables</h3>
 * <ul>
 * <li><tt>"out"</tt> : <code>response.getWriter()</code></li>
 * <li><tt>"sout"</tt> : <code>response.getOutputStream()</code></li>
 * <li><tt>"html"</tt> : <code>new MarkupBuilder(response.getWriter())</code> - <code>expandEmptyElements</code> flag is set to true</li>
 * <li><tt>"json"</tt> : <code>new JsonBuilder()</code></li>
 * </ul>
 * As per the Servlet specification, a call to <code>response.getWriter()</code> should not be
 * done if a call to <code>response.getOutputStream()</code> has already occurred or the other way
 * around. You may wonder then how the above lazy variables can possibly be provided - since
 * setting them up would involve calling both of the above methods. The trick is catered for
 * behind the scenes using lazy variables. Lazy bound variables can be requested without side
 * effects; under the covers the writer and stream are wrapped. That means
 * <code>response.getWriter()</code> is never directly called until some output is done using
 * 'out' or 'html'. Once a write method call is done using either of these variable, then an attempt
 * to write using 'sout' will cause an <code>IllegalStateException</code>. Similarly, if a write method
 * call on 'sout' has been done already, then any further write method call on 'out' or 'html' will cause an
 * <code>IllegalStateException</code>.
 * <p>
 * <h3>Reserved internal variable names (see "Methods" below)</h3>
 * <ul>
 * <li><tt>"forward"</tt></li>
 * <li><tt>"include"</tt></li>
 * <li><tt>"redirect"</tt></li>
 * </ul>
 *
 * If <code>response.getWriter()</code> is called directly (without using out), then a write method
 * call on 'sout' will not cause the <code>IllegalStateException</code>, but it will still be invalid.
 * It is the responsibility of the user of this class, to not to mix these different usage
 * styles. The same applies to calling <code>response.getOutputStream()</code> and using 'out' or 'html'.
 *
 * <h3>Methods</h3>
 * <ul>
 * <li><tt>"forward(String path)"</tt> : <code>request.getRequestDispatcher(path).forward(request, response)</code></li>
 * <li><tt>"include(String path)"</tt> : <code>request.getRequestDispatcher(path).include(request, response)</code></li>
 * <li><tt>"redirect(String location)"</tt> : <code>response.sendRedirect(location)</code></li>
 * </ul>
 */
public class ServletBinding extends Binding {
    
    /**
     * A OutputStream dummy that will throw a GroovyBugError for any
     * write method call to it. 
     */
    private static class InvalidOutputStream extends OutputStream {
        /**
         * Will always throw a GroovyBugError
         * @see java.io.OutputStream#write(int)
         */
        public void write(int b) {
            throw new GroovyBugError("Any write calls to this stream are invalid!");
        }
    }
    /**
     * A class to manage the response output stream and writer.
     * If the stream have been 'used', then using the writer will cause
     * a IllegalStateException. If the writer have been 'used', then 
     * using the stream will cause a IllegalStateException. 'used' means
     * any write method has been called. Simply requesting the objects will
     * not cause an exception. 
     */
    private static class ServletOutput {
        private final HttpServletResponse response;
        private ServletOutputStream outputStream;
        private PrintWriter writer;
        
        public ServletOutput(HttpServletResponse response) {
            this.response = response;
        }
        private ServletOutputStream getResponseStream() throws IOException {
            if (writer != null) throw new IllegalStateException("The variable 'out' or 'html' have been used already. Use either out/html or sout, not both.");
            if (outputStream == null) outputStream = response.getOutputStream();
            return outputStream;
        }
        public ServletOutputStream getOutputStream() {
            return new ServletOutputStream() {
                public void write(int b) throws IOException {
                    getResponseStream().write(b);                    
                }
                public void close() throws IOException {
                    getResponseStream().close();
                }
                public void flush() throws IOException {
                    getResponseStream().flush();
                }
                public void write(byte[] b) throws IOException {
                    getResponseStream().write(b);
                }
                public void write(byte[] b, int off, int len) throws IOException {
                    getResponseStream().write(b, off, len);
                }
            };
        }
        private PrintWriter getResponseWriter() {
            if (outputStream != null) throw new IllegalStateException("The variable 'sout' have been used already. Use either out/html or sout, not both.");
            if (writer == null) {
                try {
                    writer = response.getWriter();
                } catch (IOException ioe) {
                    writer = new PrintWriter(new ByteArrayOutputStream());
                    throw new IllegalStateException("unable to get response writer",ioe);
                }
            }
            return writer;
        }
        public PrintWriter getWriter() {
            return new PrintWriter(new InvalidOutputStream()) {
                public boolean checkError() {
                    return getResponseWriter().checkError();
                }
                public void close() {
                    getResponseWriter().close();
                }
                public void flush() {
                    getResponseWriter().flush();
                }
                public void write(char[] buf) {
                    getResponseWriter().write(buf);
                }
                public void write(char[] buf, int off, int len) {
                    getResponseWriter().write(buf, off, len);
                }
                public void write(int c) {
                    getResponseWriter().write(c);
                }
                public void write(String s, int off, int len) {
                    getResponseWriter().write(s, off, len);
                }
                public void println() {
                    getResponseWriter().println();
                }
                public PrintWriter format(String format, Object... args) {
                    getResponseWriter().format(format, args);
                    return this;
                }
                public PrintWriter format(Locale l, String format,  Object... args) {
                    getResponseWriter().format(l, format, args);
                    return this;
                }
            };
        }        
    }    
    
    private boolean initialized;

    /**
     * Initializes a servlet binding.
     *
     * @param request  the HttpServletRequest object
     * @param response the HttpServletRequest object
     * @param context  the ServletContext object
     */
    public ServletBinding(HttpServletRequest request, HttpServletResponse response, ServletContext context) {
        /*
         * Bind the default variables.
         */
        super.setVariable("request", request);
        super.setVariable("response", response);
        super.setVariable("context", context);
        super.setVariable("application", context);

        /*
         * Bind the HTTP session object - if there is one.
         * Note: we don't create one here!
         */
        super.setVariable("session", request.getSession(false));

        /*
         * Bind form parameter key-value hash map.
         *
         * If there are multiple, they are passed as an array.
         */
        Map params = collectParams(request);
        super.setVariable("params", params);

        /*
         * Bind request header key-value hash map.
         */
        Map<String, String> headers = new LinkedHashMap<String, String>();
        for (Enumeration names = request.getHeaderNames(); names.hasMoreElements();) {
            String headerName = (String) names.nextElement();
            String headerValue = request.getHeader(headerName);
            headers.put(headerName, headerValue);
        }
        super.setVariable("headers", headers);
    }

    @SuppressWarnings("unchecked")
    private Map collectParams(HttpServletRequest request) {
        Map params = new LinkedHashMap();
        for (Enumeration names = request.getParameterNames(); names.hasMoreElements();) {
            String name = (String) names.nextElement();
            if (!super.getVariables().containsKey(name)) {
                String[] values = request.getParameterValues(name);
                if (values.length == 1) {
                    params.put(name, values[0]);
                } else {
                    params.put(name, values);
                }
            }
        }
        return params;
    }

    @Override
    public void setVariable(String name, Object value) {
        lazyInit();
        validateArgs(name, "Can't bind variable to");
        excludeReservedName(name, "out");
        excludeReservedName(name, "sout");
        excludeReservedName(name, "html");
		excludeReservedName(name, "json");
        excludeReservedName(name, "forward");
        excludeReservedName(name, "include");
        excludeReservedName(name, "redirect");
        super.setVariable(name, value);
    }

    @Override
    public Map getVariables() {
        lazyInit();
        return super.getVariables();
    }

    /**
     * @return a writer, an output stream, a markup builder or another requested object
     */
    @Override
    public Object getVariable(String name) {
        lazyInit();
        validateArgs(name, "No variable with");
        return super.getVariable(name);
    }

    private void lazyInit() {
        if (initialized) return;
        initialized = true;

        HttpServletResponse response = (HttpServletResponse) super.getVariable("response");
        ServletOutput output = new ServletOutput(response);
        super.setVariable("out", output.getWriter());
        super.setVariable("sout", output.getOutputStream());

        MarkupBuilder builder = new MarkupBuilder(output.getWriter());
        builder.setExpandEmptyElements(true);
        super.setVariable("html", builder);

        try {
            Class jsonBuilderClass = this.getClass().getClassLoader().loadClass("groovy.json.StreamingJsonBuilder");
            Constructor writerConstructor = jsonBuilderClass.getConstructor(Writer.class);
            super.setVariable("json", writerConstructor.newInstance(output.getWriter()));
        } catch (Throwable t) {
            t.printStackTrace();
        }

        // bind forward method
        MethodClosure c = new MethodClosure(this, "forward");
        super.setVariable("forward", c);
        
        // bind include method
        c = new MethodClosure(this, "include");
        super.setVariable("include", c);
        
        // bind redirect method
        c = new MethodClosure(this, "redirect");
        super.setVariable("redirect", c);
    }

    private static void validateArgs(String name, String message) {
        if (name == null) {
            throw new IllegalArgumentException(message + " null key.");
        }
        if (name.length() == 0) {
            throw new IllegalArgumentException(message + " blank key name. [length=0]");
        }
    }

    private static void excludeReservedName(String name, String reservedName) {
        if (reservedName.equals(name)) {
            throw new IllegalArgumentException("Can't bind variable to key named '" + name + "'.");
        }
    }
    
    public void forward(String path) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) super.getVariable("request");
        HttpServletResponse response = (HttpServletResponse) super.getVariable("response");
        RequestDispatcher dispatcher = request.getRequestDispatcher(path);
        dispatcher.forward(request, response);
    } 
    
    public void include(String path) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) super.getVariable("request");
        HttpServletResponse response = (HttpServletResponse) super.getVariable("response");
        RequestDispatcher dispatcher = request.getRequestDispatcher(path);
        dispatcher.include(request, response);
    }

    public void redirect(String location) throws IOException {
        HttpServletResponse response = (HttpServletResponse) super.getVariable("response");
        response.sendRedirect(location);
    }    
}
