/*
 * Copyright 1999,2004 The Apache Software Foundation. Licensed 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 org.apache.catalina.ssi;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.Request;
import org.apache.coyote.Constants;

/**
 * An implementation of SSIExternalResolver that is used with servlets.
 * 
 * @author Dan Sandberg
 * @author David Becker
 * @version $Revision$, $Date$
 */
public class SSIServletExternalResolver implements SSIExternalResolver {
    protected final String VARIABLE_NAMES[] = {"AUTH_TYPE", "CONTENT_LENGTH",
            "CONTENT_TYPE", "DOCUMENT_NAME", "DOCUMENT_URI",
            "GATEWAY_INTERFACE", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",
            "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", "HTTP_HOST",
            "HTTP_REFERER", "HTTP_USER_AGENT", "PATH_INFO", "PATH_TRANSLATED",
            "QUERY_STRING", "QUERY_STRING_UNESCAPED", "REMOTE_ADDR",
            "REMOTE_HOST", "REMOTE_PORT", "REMOTE_USER", "REQUEST_METHOD",
            "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_ADDR",
            "SERVER_NAME", "SERVER_PORT", "SERVER_PROTOCOL", "SERVER_SOFTWARE",
            "UNIQUE_ID"};
    protected ServletContext context;
    protected HttpServletRequest req;
    protected HttpServletResponse res;
    protected boolean isVirtualWebappRelative;
    protected int debug;
    protected String inputEncoding;

    public SSIServletExternalResolver(ServletContext context,
            HttpServletRequest req, HttpServletResponse res,
            boolean isVirtualWebappRelative, int debug, String inputEncoding) {
        this.context = context;
        this.req = req;
        this.res = res;
        this.isVirtualWebappRelative = isVirtualWebappRelative;
        this.debug = debug;
        this.inputEncoding = inputEncoding;
    }


    public void log(String message, Throwable throwable) {
        //We can't assume that Servlet.log( message, null )
        //is the same as Servlet.log( message ), since API
        //doesn't seem to say so.
        if (throwable != null) {
            context.log(message, throwable);
        } else {
            context.log(message);
        }
    }


    public void addVariableNames(Collection variableNames) {
        for (int i = 0; i < VARIABLE_NAMES.length; i++) {
            String variableName = VARIABLE_NAMES[i];
            String variableValue = getVariableValue(variableName);
            if (variableValue != null) {
                variableNames.add(variableName);
            }
        }
        Enumeration e = req.getAttributeNames();
        while (e.hasMoreElements()) {
            String name = (String)e.nextElement();
            if (!isNameReserved(name)) {
                variableNames.add(name);
            }
        }
    }


    protected Object getReqAttributeIgnoreCase(String targetName) {
        Object object = null;
        if (!isNameReserved(targetName)) {
            object = req.getAttribute(targetName);
            if (object == null) {
                Enumeration e = req.getAttributeNames();
                while (e.hasMoreElements()) {
                    String name = (String)e.nextElement();
                    if (targetName.equalsIgnoreCase(name)
                            && !isNameReserved(name)) {
                        object = req.getAttribute(name);
                        if (object != null) {
                            break;
                        }
                    }
                }
            }
        }
        return object;
    }


    protected boolean isNameReserved(String name) {
        return name.startsWith("java.") || name.startsWith("javax.")
                || name.startsWith("sun.");
    }


    public void setVariableValue(String name, String value) {
        if (!isNameReserved(name)) {
            req.setAttribute(name, value);
        }
    }


    public String getVariableValue(String name) {
        String retVal = null;
        Object object = getReqAttributeIgnoreCase(name);
        if (object != null) {
            retVal = object.toString();
        } else {
            retVal = getCGIVariable(name);
        }
        return retVal;
    }


    protected String getCGIVariable(String name) {
        String retVal = null;
        String[] nameParts = name.toUpperCase().split("_");
        int requiredParts = 2;
        if (nameParts.length == 1) {
            if (nameParts[0].equals("PATH")) {
                requiredParts = 1;
                retVal = null; // Not implemented
            }
        }
        else if (nameParts[0].equals("AUTH")) {
            if (nameParts[1].equals("TYPE")) {
                retVal = req.getAuthType();
            }
        } else if(nameParts[0].equals("CONTENT")) {
            if (nameParts[1].equals("LENGTH")) {
                int contentLength = req.getContentLength();
                if (contentLength >= 0) {
                    retVal = Integer.toString(contentLength);
                }
            } else if (nameParts[1].equals("TYPE")) {
                retVal = req.getContentType();
            }
        } else if (nameParts[0].equals("DOCUMENT")) {
            if (nameParts[1].equals("NAME")) {
                String requestURI = req.getRequestURI();
                retVal = requestURI.substring(requestURI.lastIndexOf('/') + 1);
            } else if (nameParts[1].equals("URI")) {
                retVal = req.getRequestURI();
            }
        } else if (name.equalsIgnoreCase("GATEWAY_INTERFACE")) {
            retVal = "CGI/1.1";
        } else if (nameParts[0].equals("HTTP")) {
            if (nameParts[1].equals("ACCEPT")) {
                String accept = null;
                if (nameParts.length == 2) {
                    accept = "Accept";
                } else if (nameParts[2].equals("ENCODING")) {
                    requiredParts = 3;
                    accept = "Accept-Encoding";
                } else if (nameParts[2].equals("LANGUAGE")) {
                    requiredParts = 3;
                    accept = "Accept-Language";
                }
                if (accept != null) {
                    Enumeration acceptHeaders = req.getHeaders(accept);
                    if (acceptHeaders != null)
                        if (acceptHeaders.hasMoreElements()) {
                            StringBuffer rv = new StringBuffer(
                                    (String) acceptHeaders.nextElement());
                            while (acceptHeaders.hasMoreElements()) {
                                rv.append(", ");
                                rv.append((String) acceptHeaders.nextElement());
                            }
                        retVal = rv.toString();
                    }
                }
            }
            else if (nameParts[1].equals("CONNECTION")) {
                retVal = req.getHeader("Connection");
            }
            else if (nameParts[1].equals("HOST")) {
                retVal = req.getHeader("Host");
            }
            else if (nameParts[1].equals("REFERER")) {
                retVal = req.getHeader("Referer");
            }
            else if (nameParts[1].equals("USER"))
                if (nameParts.length == 3)
                    if (nameParts[2].equals("AGENT")) {
                        requiredParts = 3;
                        retVal = req.getHeader("User-Agent");
                    }

        } else if (nameParts[0].equals("PATH")) {
            if (nameParts[1].equals("INFO")) {
                retVal = req.getPathInfo();
            } else if (nameParts[1].equals("TRANSLATED")) {
                retVal = req.getPathTranslated();
            }
        } else if (nameParts[0].equals("QUERY")) {
            if (nameParts[1].equals("STRING")) {
                String queryString = req.getQueryString();
                if (nameParts.length == 2) {
                    //apache displays this as an empty string rather than (none)
                    retVal = nullToEmptyString(queryString);
                } else if (nameParts[2].equals("UNESCAPED")) {
                    requiredParts = 3;
                    if (queryString != null) {
                        // Use default as a last resort
                        String queryStringEncoding =
                            Constants.DEFAULT_CHARACTER_ENCODING;
                
                        String uriEncoding = null;
                        boolean useBodyEncodingForURI = false;
                
                        // Get encoding settings from request / connector if
                        // possible
                        String requestEncoding = req.getCharacterEncoding();
                        if (req instanceof Request) {
                            uriEncoding =
                                ((Request)req).getConnector().getURIEncoding();
                            useBodyEncodingForURI = ((Request)req)
                                    .getConnector().getUseBodyEncodingForURI();
                        }
                
                        // If valid, apply settings from request / connector
                        if (uriEncoding != null) {
                            queryStringEncoding = uriEncoding;
                        } else if(useBodyEncodingForURI) {
                            if (requestEncoding != null) {
                                queryStringEncoding = requestEncoding;
                            }
                        }
                
                        try {
                            retVal = URLDecoder.decode(queryString,
                                    queryStringEncoding);                       
                        } catch (UnsupportedEncodingException e) {
                            retVal = queryString;
                        }
                    }
                }
            }
        } else if(nameParts[0].equals("REMOTE")) {
            if (nameParts[1].equals("ADDR")) {
                retVal = req.getRemoteAddr();
            } else if (nameParts[1].equals("HOST")) {
                retVal = req.getRemoteHost();
            } else if (nameParts[1].equals("IDENT")) {
                retVal = null; // Not implemented
            } else if (nameParts[1].equals("PORT")) {
                retVal = Integer.toString( req.getRemotePort());
            } else if (nameParts[1].equals("USER")) {
                retVal = req.getRemoteUser();
            }
        } else if(nameParts[0].equals("REQUEST")) {
            if (nameParts[1].equals("METHOD")) {
                retVal = req.getMethod();
            }
            else if (nameParts[1].equals("URI")) {
                // If this is an error page, get the original URI
                retVal = (String) req.getAttribute(
                        "javax.servlet.forward.request_uri");
                if (retVal == null) retVal=req.getRequestURI();
            }
        } else if (nameParts[0].equals("SCRIPT")) {
            String scriptName = req.getServletPath();
            if (nameParts[1].equals("FILENAME")) {
                retVal = context.getRealPath(scriptName);
            }
            else if (nameParts[1].equals("NAME")) {
                retVal = scriptName;
            }
        } else if (nameParts[0].equals("SERVER")) {
            if (nameParts[1].equals("ADDR")) {
                retVal = req.getLocalAddr();
            }
            if (nameParts[1].equals("NAME")) {
                retVal = req.getServerName();
            } else if (nameParts[1].equals("PORT")) {
                retVal = Integer.toString(req.getServerPort());
            } else if (nameParts[1].equals("PROTOCOL")) {
                retVal = req.getProtocol();
            } else if (nameParts[1].equals("SOFTWARE")) {
                StringBuffer rv = new StringBuffer(context.getServerInfo());
                rv.append(" ");
                rv.append(System.getProperty("java.vm.name"));
                rv.append("/");
                rv.append(System.getProperty("java.vm.version"));
                rv.append(" ");
                rv.append(System.getProperty("os.name"));
                retVal = rv.toString();
            }
        } else if (name.equalsIgnoreCase("UNIQUE_ID")) {
            retVal = req.getRequestedSessionId();
        }
        if (requiredParts != nameParts.length) return null;
            return retVal;
    }

    public Date getCurrentDate() {
        return new Date();
    }


    protected String nullToEmptyString(String string) {
        String retVal = string;
        if (retVal == null) {
            retVal = "";
        }
        return retVal;
    }


    protected String getPathWithoutFileName(String servletPath) {
        String retVal = null;
        int lastSlash = servletPath.lastIndexOf('/');
        if (lastSlash >= 0) {
            //cut off file namee
            retVal = servletPath.substring(0, lastSlash + 1);
        }
        return retVal;
    }


    protected String getPathWithoutContext(String servletPath) {
        String retVal = null;
        int secondSlash = servletPath.indexOf('/', 1);
        if (secondSlash >= 0) {
            //cut off context
            retVal = servletPath.substring(secondSlash);
        }
        return retVal;
    }


    protected String getAbsolutePath(String path) throws IOException {
        String pathWithoutContext = SSIServletRequestUtil.getRelativePath(req);
        String prefix = getPathWithoutFileName(pathWithoutContext);
        if (prefix == null) {
            throw new IOException("Couldn't remove filename from path: "
                    + pathWithoutContext);
        }
        String fullPath = prefix + path;
        String retVal = SSIServletRequestUtil.normalize(fullPath);
        if (retVal == null) {
            throw new IOException("Normalization yielded null on path: "
                    + fullPath);
        }
        return retVal;
    }


    protected ServletContextAndPath getServletContextAndPathFromNonVirtualPath(
            String nonVirtualPath) throws IOException {
        if (nonVirtualPath.startsWith("/") || nonVirtualPath.startsWith("\\")) {
            throw new IOException("A non-virtual path can't be absolute: "
                    + nonVirtualPath);
        }
        if (nonVirtualPath.indexOf("../") >= 0) {
            throw new IOException("A non-virtual path can't contain '../' : "
                    + nonVirtualPath);
        }
        String path = getAbsolutePath(nonVirtualPath);
        ServletContextAndPath csAndP = new ServletContextAndPath(
                context, path);
        return csAndP;
    }


    protected ServletContextAndPath getServletContextAndPathFromVirtualPath(
            String virtualPath) throws IOException {

        if (!virtualPath.startsWith("/") && !virtualPath.startsWith("\\")) {
            return new ServletContextAndPath(context,
                    getAbsolutePath(virtualPath));
        } else {
            String normalized = SSIServletRequestUtil.normalize(virtualPath);
            if (isVirtualWebappRelative) {
                return new ServletContextAndPath(context, normalized);
            } else {
                ServletContext normContext = context.getContext(normalized);
                if (normContext == null) {
                    throw new IOException("Couldn't get context for path: "
                            + normalized);
                }
                //If it's the root context, then there is no context element
                // to remove,
                // ie:
                // '/file1.shtml' vs '/appName1/file1.shtml'
                if (!isRootContext(normContext)) {
                    String noContext = getPathWithoutContext(normalized);
                    if (noContext == null) {
                        throw new IOException(
                                "Couldn't remove context from path: "
                                        + normalized);
                    }
                    return new ServletContextAndPath(normContext, noContext);
                } else {
                    return new ServletContextAndPath(normContext, normalized);
                }
            }
        }
    }


    //Assumes servletContext is not-null
    //Assumes that identity comparison will be true for the same context
    //Assuming the above, getContext("/") will be non-null as long as the root
    // context is
    // accessible.
    //If it isn't, then servletContext can't be the root context anyway, hence
    // they will
    // not match.
    protected boolean isRootContext(ServletContext servletContext) {
        return servletContext == servletContext.getContext("/");
    }


    protected ServletContextAndPath getServletContextAndPath(
            String originalPath, boolean virtual) throws IOException {
        ServletContextAndPath csAndP = null;
        if (debug > 0) {
            log("SSIServletExternalResolver.getServletContextAndPath( "
                    + originalPath + ", " + virtual + ")", null);
        }
        if (virtual) {
            csAndP = getServletContextAndPathFromVirtualPath(originalPath);
        } else {
            csAndP = getServletContextAndPathFromNonVirtualPath(originalPath);
        }
        return csAndP;
    }


    protected URLConnection getURLConnection(String originalPath,
            boolean virtual) throws IOException {
        ServletContextAndPath csAndP = getServletContextAndPath(originalPath,
                virtual);
        ServletContext context = csAndP.getServletContext();
        String path = csAndP.getPath();
        URL url = context.getResource(path);
        if (url == null) {
            throw new IOException("Context did not contain resource: " + path);
        }
        URLConnection urlConnection = url.openConnection();
        return urlConnection;
    }


    public long getFileLastModified(String path, boolean virtual)
            throws IOException {
        long lastModified = 0;
        try {
            URLConnection urlConnection = getURLConnection(path, virtual);
            lastModified = urlConnection.getLastModified();
        } catch (IOException e) {
            // Ignore this. It will always fail for non-file based includes
        }
        return lastModified;
    }


    public long getFileSize(String path, boolean virtual) throws IOException {
        long fileSize = -1;
        try {
            URLConnection urlConnection = getURLConnection(path, virtual);
            fileSize = urlConnection.getContentLength();
        } catch (IOException e) {
            // Ignore this. It will always fail for non-file based includes
        }
        return fileSize;
    }


    //We are making lots of unnecessary copies of the included data here. If
    //someone ever complains that this is slow, we should connect the included
    // stream to the print writer that SSICommand uses.
    public String getFileText(String originalPath, boolean virtual)
            throws IOException {
        try {
            ServletContextAndPath csAndP = getServletContextAndPath(
                    originalPath, virtual);
            ServletContext context = csAndP.getServletContext();
            String path = csAndP.getPath();
            RequestDispatcher rd = context.getRequestDispatcher(path);
            if (rd == null) {
                throw new IOException(
                        "Couldn't get request dispatcher for path: " + path);
            }
            ByteArrayServletOutputStream basos =
                new ByteArrayServletOutputStream();
            ResponseIncludeWrapper responseIncludeWrapper =
                new ResponseIncludeWrapper(context, req, res, basos);
            rd.include(req, responseIncludeWrapper);
            //We can't assume the included servlet flushed its output
            responseIncludeWrapper.flushOutputStreamOrWriter();
            byte[] bytes = basos.toByteArray();

            //Assume platform default encoding unless otherwise specified
            String retVal;
            if (inputEncoding == null) {
                retVal = new String( bytes );
            } else {
                retVal = new String (bytes, inputEncoding);
            }

            //make an assumption that an empty response is a failure. This is
            // a problem
            // if a truly empty file
            //were included, but not sure how else to tell.
            if (retVal.equals("") && !req.getMethod().equalsIgnoreCase(
                    org.apache.coyote.http11.Constants.HEAD)) {
                throw new IOException("Couldn't find file: " + path);
            }
            return retVal;
        } catch (ServletException e) {
            throw new IOException("Couldn't include file: " + originalPath
                    + " because of ServletException: " + e.getMessage());
        }
    }

    protected class ServletContextAndPath {
        protected ServletContext servletContext;
        protected String path;


        public ServletContextAndPath(ServletContext servletContext,
                                     String path) {
            this.servletContext = servletContext;
            this.path = path;
        }


        public ServletContext getServletContext() {
            return servletContext;
        }


        public String getPath() {
            return path;
        }
    }
}