//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server.handler;

import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

import javax.servlet.AsyncContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.WriterOutputStream;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;


/* ------------------------------------------------------------ */
/** Resource Handler.
 *
 * This handle will serve static content and handle If-Modified-Since headers.
 * No caching is done.
 * Requests for resources that do not exist are let pass (Eg no 404's).
 *
 *
 */
public class ResourceHandler extends HandlerWrapper implements ResourceFactory
{
    private static final Logger LOG = Log.getLogger(ResourceHandler.class);

    ContextHandler _context;
    Resource _baseResource;
    Resource _defaultStylesheet;
    Resource _stylesheet;
    String[] _welcomeFiles={"index.html"};
    MimeTypes _mimeTypes;
    String _cacheControl;
    boolean _directory;
    boolean _gzip;
    boolean _etags;
    int _minMemoryMappedContentLength=0;
    int _minAsyncContentLength=16*1024;

    /* ------------------------------------------------------------ */
    public ResourceHandler()
    {

    }

    /* ------------------------------------------------------------ */
    public MimeTypes getMimeTypes()
    {
        return _mimeTypes;
    }

    /* ------------------------------------------------------------ */
    public void setMimeTypes(MimeTypes mimeTypes)
    {
        _mimeTypes = mimeTypes;
    }

    /* ------------------------------------------------------------ */
    /** Get the directory option.
     * @return true if directories are listed.
     */
    public boolean isDirectoriesListed()
    {
        return _directory;
    }

    /* ------------------------------------------------------------ */
    /** Set the directory.
     * @param directory true if directories are listed.
     */
    public void setDirectoriesListed(boolean directory)
    {
        _directory = directory;
    }

    /* ------------------------------------------------------------ */
    /** Get minimum memory mapped file content length.
     * @return the minimum size in bytes of a file resource that will
     * be served using a memory mapped buffer, or -1 (default) for no memory mapped
     * buffers.
     */
    public int getMinMemoryMappedContentLength()
    {
        return _minMemoryMappedContentLength;
    }

    /* ------------------------------------------------------------ */
    /** Set minimum memory mapped file content length.
     * @param minMemoryMappedFileSize the minimum size in bytes of a file resource that will
     * be served using a memory mapped buffer, or -1 for no memory mapped
     * buffers.
     */
    public void setMinMemoryMappedContentLength(int minMemoryMappedFileSize)
    {
        _minMemoryMappedContentLength = minMemoryMappedFileSize;
    }

    /* ------------------------------------------------------------ */
    /** Get the minimum content length for async handling.
     * @return The minimum size in bytes of the content before asynchronous 
     * handling is used, or -1 for no async handling or 0 (default) for using
     * {@link HttpServletResponse#getBufferSize()} as the minimum length.
     */
    public int getMinAsyncContentLength()
    {
        return _minAsyncContentLength;
    }

    /* ------------------------------------------------------------ */
    /** Set the minimum content length for async handling.
     * @param minAsyncContentLength The minimum size in bytes of the content before asynchronous 
     * handling is used, or -1 for no async handling or 0 for using
     * {@link HttpServletResponse#getBufferSize()} as the minimum length.
     */
    public void setMinAsyncContentLength(int minAsyncContentLength)
    {
        _minAsyncContentLength = minAsyncContentLength;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return True if ETag processing is done
     */
    public boolean isEtags()
    {
        return _etags;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param etags True if ETag processing is done
     */
    public void setEtags(boolean etags)
    {
        _etags = etags;
    }

    /* ------------------------------------------------------------ */
    @Override
    public void doStart()
    throws Exception
    {
        Context scontext = ContextHandler.getCurrentContext();
        _context = (scontext==null?null:scontext.getContextHandler());
        _mimeTypes = _context==null?new MimeTypes():_context.getMimeTypes();
        
        super.doStart();
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the resourceBase.
     */
    public Resource getBaseResource()
    {
        if (_baseResource==null)
            return null;
        return _baseResource;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the base resource as a string.
     */
    public String getResourceBase()
    {
        if (_baseResource==null)
            return null;
        return _baseResource.toString();
    }


    /* ------------------------------------------------------------ */
    /**
     * @param base The resourceBase to set.
     */
    public void setBaseResource(Resource base)
    {
        _baseResource=base;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param resourceBase The base resource as a string.
     */
    public void setResourceBase(String resourceBase)
    {
        try
        {
            setBaseResource(Resource.newResource(resourceBase));
        }
        catch (Exception e)
        {
            LOG.warn(e.toString());
            LOG.debug(e);
            throw new IllegalArgumentException(resourceBase);
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the stylesheet as a Resource.
     */
    public Resource getStylesheet()
    {
        if(_stylesheet != null)
        {
            return _stylesheet;
        }
        else
        {
            if(_defaultStylesheet == null)
            {
                _defaultStylesheet =  Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
            }
            return _defaultStylesheet;
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @param stylesheet The location of the stylesheet to be used as a String.
     */
    public void setStylesheet(String stylesheet)
    {
        try
        {
            _stylesheet = Resource.newResource(stylesheet);
            if(!_stylesheet.exists())
            {
                LOG.warn("unable to find custom stylesheet: " + stylesheet);
                _stylesheet = null;
            }
        }
        catch(Exception e)
        {
            LOG.warn(e.toString());
            LOG.debug(e);
            throw new IllegalArgumentException(stylesheet);
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @return the cacheControl header to set on all static content.
     */
    public String getCacheControl()
    {
        return _cacheControl;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param cacheControl the cacheControl header to set on all static content.
     */
    public void setCacheControl(String cacheControl)
    {
        _cacheControl=cacheControl;
    }

    /* ------------------------------------------------------------ */
    /*
     */
    @Override
    public Resource getResource(String path)
    {
        if (LOG.isDebugEnabled())
            LOG.debug("{} getResource({})",_context==null?_baseResource:_context,_baseResource,path);

        if (path==null || !path.startsWith("/"))
            return null;
        
        try
        {
            Resource base = _baseResource;
            if (base==null)
            {
                if (_context==null)
                    return null;
                return _context.getResource(path);
            }

            path=URIUtil.canonicalPath(path);
            Resource r = base.addPath(path);
            if (r!=null && r.isAlias() && (_context==null || !_context.checkAlias(path, r)))
            {
                if (LOG.isDebugEnabled())
                    LOG.debug("resource={} alias={}",r,r.getAlias());
                return null;
            }
            return r;
        }
        catch(Exception e)
        {
            LOG.debug(e);
        }

        return null;
    }

    /* ------------------------------------------------------------ */
    protected Resource getResource(HttpServletRequest request) throws MalformedURLException
    {
        String servletPath;
        String pathInfo;
        Boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
        if (included != null && included.booleanValue())
        {
            servletPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
            pathInfo = (String)request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);

            if (servletPath == null && pathInfo == null)
            {
                servletPath = request.getServletPath();
                pathInfo = request.getPathInfo();
            }
        }
        else
        {
            servletPath = request.getServletPath();
            pathInfo = request.getPathInfo();
        }

        String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
        return getResource(pathInContext);
    }


    /* ------------------------------------------------------------ */
    public String[] getWelcomeFiles()
    {
        return _welcomeFiles;
    }

    /* ------------------------------------------------------------ */
    public void setWelcomeFiles(String[] welcomeFiles)
    {
        _welcomeFiles=welcomeFiles;
    }

    /* ------------------------------------------------------------ */
    protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException
    {
        for (int i=0;i<_welcomeFiles.length;i++)
        {
            Resource welcome=directory.addPath(_welcomeFiles[i]);
            if (welcome.exists() && !welcome.isDirectory())
                return welcome;
        }

        return null;
    }

    /* ------------------------------------------------------------ */
    /*
     * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
     */
    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        if (baseRequest.isHandled())
            return;

        boolean skipContentBody = false;

        if(!HttpMethod.GET.is(request.getMethod()))
        {
            if(!HttpMethod.HEAD.is(request.getMethod()))
            {
                //try another handler
                super.handle(target, baseRequest, request, response);
                return;
            }
            skipContentBody = true;
        }

        Resource resource = getResource(request);
        
        if (LOG.isDebugEnabled())
        { 
            if (resource==null)
                LOG.debug("resource=null");
            else
                LOG.debug("resource={} alias={} exists={}",resource,resource.getAlias(),resource.exists());
        }
        
        
        // If resource is not found
        if (resource==null || !resource.exists())
        {
            // inject the jetty-dir.css file if it matches
            if (target.endsWith("/jetty-dir.css"))
            {
                resource = getStylesheet();
                if (resource==null)
                    return;
                response.setContentType("text/css");
            }
            else
            {
                //no resource - try other handlers
                super.handle(target, baseRequest, request, response);
                return;
            }
        }

        // We are going to serve something
        baseRequest.setHandled(true);

        // handle directories
        if (resource.isDirectory())
        {
            String pathInfo = request.getPathInfo();
            boolean endsWithSlash=(pathInfo==null?request.getServletPath():pathInfo).endsWith(URIUtil.SLASH);
            if (!endsWithSlash)
            {
                response.sendRedirect(response.encodeRedirectURL(request.getRequestURI()+URIUtil.SLASH));
                return;
            }

            Resource welcome=getWelcome(resource);
            if (welcome!=null && welcome.exists())
                resource=welcome;
            else
            {
                doDirectory(request,response,resource);
                baseRequest.setHandled(true);
                return;
            }
        }

        // Handle ETAGS
        long last_modified=resource.lastModified();
        String etag=null;
        if (_etags)
        {
            // simple handling of only a single etag
            String ifnm = request.getHeader(HttpHeader.IF_NONE_MATCH.asString());
            etag=resource.getWeakETag();
            if (ifnm!=null && resource!=null && ifnm.equals(etag))
            {
                response.setStatus(HttpStatus.NOT_MODIFIED_304);
                baseRequest.getResponse().getHttpFields().put(HttpHeader.ETAG,etag);
                return;
            }
        }
        
        // Handle if modified since 
        if (last_modified>0)
        {
            long if_modified=request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString());
            if (if_modified>0 && last_modified/1000<=if_modified/1000)
            {
                response.setStatus(HttpStatus.NOT_MODIFIED_304);
                return;
            }
        }

        // set the headers
        String mime=_mimeTypes.getMimeByExtension(resource.toString());
        if (mime==null)
            mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
        doResponseHeaders(response,resource,mime);
        if (_etags)
            baseRequest.getResponse().getHttpFields().put(HttpHeader.ETAG,etag);
        if (last_modified>0)
            response.setDateHeader(HttpHeader.LAST_MODIFIED.asString(),last_modified);
        
        if(skipContentBody)
            return;
        
        // Send the content
        OutputStream out =null;
        try {out = response.getOutputStream();}
        catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}

        // Has the output been wrapped
        if (!(out instanceof HttpOutput))
            // Write content via wrapped output
            resource.writeTo(out,0,resource.length());
        else
        {
            // select async by size
            int min_async_size=_minAsyncContentLength==0?response.getBufferSize():_minAsyncContentLength;
            
            if (request.isAsyncSupported() && 
                min_async_size>0 &&
                resource.length()>=min_async_size)
            {
                final AsyncContext async = request.startAsync();
                async.setTimeout(0);
                Callback callback = new Callback()
                {
                    @Override
                    public void succeeded()
                    {
                        async.complete();
                    }

                    @Override
                    public void failed(Throwable x)
                    {
                        LOG.warn(x.toString());
                        LOG.debug(x);
                        async.complete();
                    }   
                };

                // Can we use a memory mapped file?
                if (_minMemoryMappedContentLength>=0 && 
                    resource.length()>_minMemoryMappedContentLength &&
                    resource.length()<Integer.MAX_VALUE &&
                    resource instanceof PathResource)
                {
                    ByteBuffer buffer = BufferUtil.toMappedBuffer(resource.getFile());
                    ((HttpOutput)out).sendContent(buffer,callback);
                }
                else  // Do a blocking write of a channel (if available) or input stream
                {
                    // Close of the channel/inputstream is done by the async sendContent
                    ReadableByteChannel channel= resource.getReadableByteChannel();
                    if (channel!=null)
                        ((HttpOutput)out).sendContent(channel,callback);
                    else
                        ((HttpOutput)out).sendContent(resource.getInputStream(),callback);
                }
            }
            else
            {
                // Can we use a memory mapped file?
                if (_minMemoryMappedContentLength>0 && 
                    resource.length()>_minMemoryMappedContentLength &&
                    resource instanceof PathResource)
                {
                    ByteBuffer buffer = BufferUtil.toMappedBuffer(resource.getFile());
                    ((HttpOutput)out).sendContent(buffer);
                }
                else  // Do a blocking write of a channel (if available) or input stream
                {
                    ReadableByteChannel channel= resource.getReadableByteChannel();
                    if (channel!=null)
                        ((HttpOutput)out).sendContent(channel);
                    else
                        ((HttpOutput)out).sendContent(resource.getInputStream());
                }
            }
        }
    }

    /* ------------------------------------------------------------ */
    protected void doDirectory(HttpServletRequest request,HttpServletResponse response, Resource resource)
        throws IOException
    {
        if (_directory)
        {
            String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0);
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().println(listing);
        }
        else
            response.sendError(HttpStatus.FORBIDDEN_403);
    }

    /* ------------------------------------------------------------ */
    /** Set the response headers.
     * This method is called to set the response headers such as content type and content length.
     * May be extended to add additional headers.
     * @param response the http response
     * @param resource the resource
     * @param mimeType the mime type
     */
    protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType)
    {
        if (mimeType!=null)
            response.setContentType(mimeType);

        long length=resource.length();

        if (response instanceof Response)
        {
            HttpFields fields = ((Response)response).getHttpFields();

            if (length>0)
                ((Response)response).setLongContentLength(length);

            if (_cacheControl!=null)
                fields.put(HttpHeader.CACHE_CONTROL,_cacheControl);
        }
        else
        {
            if (length>Integer.MAX_VALUE)
                response.setHeader(HttpHeader.CONTENT_LENGTH.asString(),Long.toString(length));
            else if (length>0)
                response.setContentLength((int)length);

            if (_cacheControl!=null)
                response.setHeader(HttpHeader.CACHE_CONTROL.asString(),_cacheControl);
        }
    }
}
