//
//  ========================================================================
//  Copyright (c) 1995-2014 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.servlets;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.URIUtil;

/**
 * PutFilter
 * 
 * A Filter that handles PUT, DELETE and MOVE methods.
 * Files are hidden during PUT operations, so that 404's result.
 * 
 * The following init parameters pay be used:<ul>
 * <li><b>baseURI</b> - The file URI of the document root for put content.
 * <li><b>delAllowed</b> - boolean, if true DELETE and MOVE methods are supported.
 * <li><b>putAtomic</b> - boolean, if true PUT files are written to a temp location and moved into place.
 * </ul>
 *
 */
public class PutFilter implements Filter 
{
    public final static String __PUT="PUT";
    public final static String __DELETE="DELETE";
    public final static String __MOVE="MOVE";
    public final static String __OPTIONS="OPTIONS";

    Set<String> _operations = new HashSet<String>();
    private ConcurrentMap<String,String> _hidden = new ConcurrentHashMap<String, String>();

    private ServletContext _context;
    private String _baseURI;
    private boolean _delAllowed;
    private boolean _putAtomic;
    private File _tmpdir;
    
    
    /* ------------------------------------------------------------ */
    public void init(FilterConfig config) throws ServletException
    {
        _context=config.getServletContext();
        
        _tmpdir=(File)_context.getAttribute("javax.servlet.context.tempdir");
            
        if (_context.getRealPath("/")==null)
           throw new UnavailableException("Packed war");
        
        String b = config.getInitParameter("baseURI");
        if (b != null)
        {
            _baseURI=b;
        }
        else
        {
            File base=new File(_context.getRealPath("/"));
            _baseURI=base.toURI().toString();
        }
        
        _delAllowed = getInitBoolean(config,"delAllowed");
        _putAtomic = getInitBoolean(config,"putAtomic");

        _operations.add(__OPTIONS);
        _operations.add(__PUT);
        if (_delAllowed)
        {
            _operations.add(__DELETE);
            _operations.add(__MOVE);
        }
    }

    /* ------------------------------------------------------------ */
    private boolean getInitBoolean(FilterConfig config,String name)
    {
        String value = config.getInitParameter(name);
        return value != null && value.length() > 0 && (value.startsWith("t") || value.startsWith("T") || value.startsWith("y") || value.startsWith("Y") || value.startsWith("1"));
    }

    /* ------------------------------------------------------------ */
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
    {
        HttpServletRequest request=(HttpServletRequest)req;
        HttpServletResponse response=(HttpServletResponse)res;

        String servletPath =request.getServletPath();
        String pathInfo = request.getPathInfo();
        String pathInContext = URIUtil.addPaths(servletPath, pathInfo);    

        String resource = URIUtil.addPaths(_baseURI,pathInContext); 
       
        String method = request.getMethod();
        boolean op = _operations.contains(method);
        
        if (op)
        {
            File file = null;
            try
            {
                if (method.equals(__OPTIONS))
                    handleOptions(chain,request, response);
                else
                {
                    file=new File(new URI(resource));
                    boolean exists = file.exists();
                    if (exists && !passConditionalHeaders(request, response, file))
                        return;
                    
                    if (method.equals(__PUT))
                        handlePut(request, response,pathInContext, file);
                    else if (method.equals(__DELETE))
                        handleDelete(request, response, pathInContext, file);
                    else if (method.equals(__MOVE))
                        handleMove(request, response, pathInContext, file);
                    else
                        throw new IllegalStateException();
                }
            }
            catch(Exception e)
            {
                _context.log(e.toString(),e);
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        }
        else
        {
            if (isHidden(pathInContext))
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
            else
                chain.doFilter(request,response);
            return;
        }
    }

    /* ------------------------------------------------------------ */
    private boolean isHidden(String pathInContext)
    {
        return _hidden.containsKey(pathInContext);
    }

    /* ------------------------------------------------------------ */
    public void destroy()
    {
    }

    /* ------------------------------------------------------------------- */
    public void handlePut(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) throws ServletException, IOException
    {
        boolean exists = file.exists();
        if (pathInContext.endsWith("/"))
        {
            if (!exists)
            {
                if (!file.mkdirs())
                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
                else
                {
                    response.setStatus(HttpServletResponse.SC_CREATED);
                    response.flushBuffer();
                }
            }
            else
            {
                response.setStatus(HttpServletResponse.SC_OK);
                response.flushBuffer();
            }
        }
        else
        {
            boolean ok=false;
            try
            {
                _hidden.put(pathInContext,pathInContext);
                File parent = file.getParentFile();
                parent.mkdirs();
                int toRead = request.getContentLength();
                InputStream in = request.getInputStream();
                
                    
                if (_putAtomic)
                {
                    File tmp=File.createTempFile(file.getName(),null,_tmpdir);
                    OutputStream out = new FileOutputStream(tmp,false);
                    if (toRead >= 0)
                        IO.copy(in, out, toRead);
                    else
                        IO.copy(in, out);
                    out.close();
                    
                    if (!tmp.renameTo(file))
                        throw new IOException("rename from "+tmp+" to "+file+" failed");
                }
                else
                {
                    OutputStream out = new FileOutputStream(file,false);
                    if (toRead >= 0)
                        IO.copy(in, out, toRead);
                    else
                        IO.copy(in, out);
                    out.close();
                }

                response.setStatus(exists ? HttpServletResponse.SC_OK : HttpServletResponse.SC_CREATED);
                response.flushBuffer();
                ok=true;
            }
            catch (Exception ex)
            {
                _context.log(ex.toString(),ex);
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
            }
            finally
            {
                if (!ok)
                {
                    try
                    {
                        if (file.exists())
                            file.delete();
                    }
                    catch(Exception e)
                    {
                        _context.log(e.toString(),e);
                    }
                }
                _hidden.remove(pathInContext);
            }
        }
    }

    /* ------------------------------------------------------------------- */
    public void handleDelete(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) throws ServletException, IOException
    {
        try
        {
            // delete the file
            if (file.delete())
            {
                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
                response.flushBuffer();
            }
            else
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
        }
        catch (SecurityException sex)
        {
            _context.log(sex.toString(),sex);
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
        }
    }

    /* ------------------------------------------------------------------- */
    public void handleMove(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) 
        throws ServletException, IOException, URISyntaxException
    {
        String newPath = URIUtil.canonicalPath(request.getHeader("new-uri"));
        if (newPath == null)
        {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        
        String contextPath = request.getContextPath();
        if (contextPath != null && !newPath.startsWith(contextPath))
        {
            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }
        String newInfo = newPath;
        if (contextPath != null)
            newInfo = newInfo.substring(contextPath.length());

        String new_resource = URIUtil.addPaths(_baseURI,newInfo);
        File new_file=new File(new URI(new_resource));

        file.renameTo(new_file);

        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        response.flushBuffer();
    }

    /* ------------------------------------------------------------ */
    public void handleOptions(FilterChain chain, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        chain.doFilter(request,new HttpServletResponseWrapper(response)
        {
            @Override
            public void setHeader(String name, String value)
            {
                if ("Allow".equalsIgnoreCase(name))
                {
                    Set<String> options = new HashSet<String>();
                    options.addAll(Arrays.asList(value.split(" *, *")));
                    options.addAll(_operations);
                    value=null;
                    for (String o : options)
                        value=value==null?o:(value+", "+o);
                }
                    
                super.setHeader(name,value);
            }
        });
        
    }

    /* ------------------------------------------------------------ */
    /*
     * Check modification date headers.
     */
    protected boolean passConditionalHeaders(HttpServletRequest request, HttpServletResponse response, File file) throws IOException
    {
        long date = 0;
        
        if ((date = request.getDateHeader("if-unmodified-since")) > 0)
        {
            if (file.lastModified() / 1000 > date / 1000)
            {
                response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
                return false;
            }
        }

        if ((date = request.getDateHeader("if-modified-since")) > 0)
        {
            if (file.lastModified() / 1000 <= date / 1000)
            {
                response.reset();
                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                response.flushBuffer();
                return false;
            }
        }
        return true;
    }
}
