//
//  ========================================================================
//  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.servlets.gzip;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.eclipse.jetty.util.IncludeExclude;
import org.eclipse.jetty.util.StringUtil;

/*------------------------------------------------------------ */
/**
 */
public abstract class CompressedResponseWrapper extends HttpServletResponseWrapper
{

    public static final int DEFAULT_BUFFER_SIZE = 8192;
    public static final int DEFAULT_MIN_COMPRESS_SIZE = 256;

    private IncludeExclude<String> _mimeTypes;
    private int _bufferSize=DEFAULT_BUFFER_SIZE;
    private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE;
    protected HttpServletRequest _request;

    private PrintWriter _writer;
    private AbstractCompressedStream _compressedStream;
    private String _etag;
    private long _contentLength=-1;
    private boolean _noCompression;

    /* ------------------------------------------------------------ */
    public CompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response)
    {
        super(response);
        _request = request;
    }


    /* ------------------------------------------------------------ */
    public long getContentLength()
    {
        return _contentLength;
    }

    /* ------------------------------------------------------------ */
    @Override
    public int getBufferSize()
    {
        return _bufferSize;
    }
    
    /* ------------------------------------------------------------ */
    public int getMinCompressSize()
    {
        return _minCompressSize;
    }
    
    /* ------------------------------------------------------------ */
    public String getETag()
    {
        return _etag;
    }

    /* ------------------------------------------------------------ */
    public HttpServletRequest getRequest()
    {
        return _request;
    }
    
    /* ------------------------------------------------------------ */
    /**
     */
    public void setMimeTypes(IncludeExclude<String> mimeTypes)
    {
        _mimeTypes = mimeTypes;
    }

    /* ------------------------------------------------------------ */
    /**
     */
    @Override
    public void setBufferSize(int bufferSize)
    {
        _bufferSize = bufferSize;
        if (_compressedStream!=null)
            _compressedStream.setBufferSize(bufferSize);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setMinCompressSize(int)
     */
    public void setMinCompressSize(int minCompressSize)
    {
        _minCompressSize = minCompressSize;
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setContentType(java.lang.String)
     */
    @Override
    public void setContentType(String ct)
    {
        super.setContentType(ct);

        if (!_noCompression && (_compressedStream==null || _compressedStream.getOutputStream()==null))
        {
            if (ct!=null)
            {
                int colon=ct.indexOf(";");
                if (colon>0)
                    ct=ct.substring(0,colon);

                if (!_mimeTypes.matches(StringUtil.asciiToLowerCase(ct)))
                    noCompression();
            }
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String)
     */
    @SuppressWarnings("deprecation")
    @Override
    public void setStatus(int sc, String sm)
    {
        super.setStatus(sc,sm);
        if (sc<200 || sc==204 || sc==205 || sc>=300)
            noCompression();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setStatus(int)
     */
    @Override
    public void setStatus(int sc)
    {
        super.setStatus(sc);
        if (sc<200 || sc==204 || sc==205 || sc>=300)
            noCompression();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setContentLength(int)
     */
    @Override
    public void setContentLength(int length)
    {
        if (_noCompression)
            super.setContentLength(length);
        else
            setContentLength((long)length);
    }

    /* ------------------------------------------------------------ */
    protected void setContentLength(long length)
    {
        _contentLength=length;
        if (_compressedStream!=null)
            _compressedStream.setContentLength();
        else if (_noCompression && _contentLength>=0)
        {
            HttpServletResponse response = (HttpServletResponse)getResponse();
            if(_contentLength<Integer.MAX_VALUE)
            {
                response.setContentLength((int)_contentLength);
            }
            else
            {
                response.setHeader("Content-Length", Long.toString(_contentLength));
            }
        }
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#addHeader(java.lang.String, java.lang.String)
     */
    @Override
    public void addHeader(String name, String value)
    {
        if ("content-length".equalsIgnoreCase(name))
        {
            _contentLength=Long.parseLong(value);
            if (_compressedStream!=null)
                _compressedStream.setContentLength();
        }
        else if ("content-type".equalsIgnoreCase(name))
        {
            setContentType(value);
        }
        else if ("content-encoding".equalsIgnoreCase(name))
        {
            super.addHeader(name,value);
            if (!isCommitted())
            {
                noCompression();
            }
        }
        else if ("etag".equalsIgnoreCase(name))
            _etag=value;
        else
            super.addHeader(name,value);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#flushBuffer()
     */
    @Override
    public void flushBuffer() throws IOException
    {
        if (_writer!=null)
            _writer.flush();
        if (_compressedStream!=null)
            _compressedStream.flush();
        else
            getResponse().flushBuffer();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#reset()
     */
    @Override
    public void reset()
    {
        super.reset();
        if (_compressedStream!=null)
            _compressedStream.resetBuffer();
        _writer=null;
        _compressedStream=null;
        _noCompression=false;
        _contentLength=-1;
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#resetBuffer()
     */
    @Override
    public void resetBuffer()
    {
        super.resetBuffer();
        if (_compressedStream!=null)
            _compressedStream.resetBuffer();
        _writer=null;
        _compressedStream=null;
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#sendError(int, java.lang.String)
     */
    @Override
    public void sendError(int sc, String msg) throws IOException
    {
        resetBuffer();
        super.sendError(sc,msg);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#sendError(int)
     */
    @Override
    public void sendError(int sc) throws IOException
    {
        resetBuffer();
        super.sendError(sc);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#sendRedirect(java.lang.String)
     */
    @Override
    public void sendRedirect(String location) throws IOException
    {
        resetBuffer();
        super.sendRedirect(location);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#noCompression()
     */
    public void noCompression()
    {
        if (!_noCompression)
            setDeferredHeaders();
        _noCompression=true;
        if (_compressedStream!=null)
        {
            try
            {
                _compressedStream.doNotCompress(false);
            }
            catch (IOException e)
            {
                throw new IllegalStateException(e);
            }
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#finish()
     */
    public void finish() throws IOException
    {
        if (_writer!=null && !_compressedStream.isClosed())
            _writer.flush();
        if (_compressedStream!=null)
            _compressedStream.finish();
        else 
            setDeferredHeaders();
    }

    /* ------------------------------------------------------------ */
    private void setDeferredHeaders()
    {
        if (!isCommitted())
        {
            if (_contentLength>=0)
            {
                if (_contentLength < Integer.MAX_VALUE)
                    super.setContentLength((int)_contentLength);
                else
                    super.setHeader("Content-Length",Long.toString(_contentLength));
            }
            if(_etag!=null)
                super.setHeader("ETag",_etag);
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setHeader(java.lang.String, java.lang.String)
     */
    @Override
    public void setHeader(String name, String value)
    {
        if (_noCompression)
            super.setHeader(name,value);
        else if ("content-length".equalsIgnoreCase(name))
        {
            setContentLength(Long.parseLong(value));
        }
        else if ("content-type".equalsIgnoreCase(name))
        {
            setContentType(value);
        }
        else if ("content-encoding".equalsIgnoreCase(name))
        {
            super.setHeader(name,value);
            if (!isCommitted())
            {
                noCompression();
            }
        }
        else if ("etag".equalsIgnoreCase(name))
            _etag=value;
        else
            super.setHeader(name,value);
    }

    /* ------------------------------------------------------------ */
    @Override
    public boolean containsHeader(String name)
    {
        if (!_noCompression && "etag".equalsIgnoreCase(name) && _etag!=null)
            return true;
        return super.containsHeader(name);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#getOutputStream()
     */
    @Override
    public ServletOutputStream getOutputStream() throws IOException
    {
        if (_compressedStream==null)
        {
            if (getResponse().isCommitted() || _noCompression)
                return getResponse().getOutputStream();

            _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse());
        }
        else if (_writer!=null)
            throw new IllegalStateException("getWriter() called");

        return _compressedStream;
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#getWriter()
     */
    @Override
    public PrintWriter getWriter() throws IOException
    {
        if (_writer==null)
        {
            if (_compressedStream!=null)
                throw new IllegalStateException("getOutputStream() called");

            if (getResponse().isCommitted() || _noCompression)
                return getResponse().getWriter();

            _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse());
            _writer=newWriter(_compressedStream,getCharacterEncoding());
        }
        return _writer;
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setIntHeader(java.lang.String, int)
     */
    @Override
    public void setIntHeader(String name, int value)
    {
        if ("content-length".equalsIgnoreCase(name))
        {
            _contentLength=value;
            if (_compressedStream!=null)
                _compressedStream.setContentLength();
        }
        else
            super.setIntHeader(name,value);
    }

    /* ------------------------------------------------------------ */
    /**
     * Allows derived implementations to replace PrintWriter implementation.
     *
     * @param out the out
     * @param encoding the encoding
     * @return the prints the writer
     * @throws UnsupportedEncodingException the unsupported encoding exception
     */
    protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
    {
        return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
    }

    /* ------------------------------------------------------------ */
    /**
     *@return the underlying CompressedStream implementation
     */
    protected abstract AbstractCompressedStream newCompressedStream(HttpServletRequest _request, HttpServletResponse response) throws IOException;

}
