/*
 * 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 org.apache.sling.servlets.get.impl.helpers;

import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;
import static org.apache.sling.api.servlets.HttpConstants.HEADER_IF_MODIFIED_SINCE;
import static org.apache.sling.api.servlets.HttpConstants.HEADER_LAST_MODIFIED;

import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.StringTokenizer;

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 org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.SlingConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestDispatcherOptions;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceNotFoundException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.external.ExternalizableInputStream;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.servlets.get.impl.DefaultGetServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The <code>StreamRendererServlet</code> streams the current resource to the
 * client on behalf of the
 * {@link org.apache.sling.servlets.get.impl.DefaultGetServlet}. If the current
 * resource cannot be streamed it is rendered using the
 * {@link PlainTextRenderer}.
 */
public class StreamRenderer implements Renderer {

    /**
     * MIME multipart separation string
     */
    private static final String mimeSeparation = "SLING_MIME_BOUNDARY";

    // size threshold for sending an Accept-Ranges header back in the response (100KB)
    private static final int ACCEPT_RANGES_THRESHOLD = 100 * 1024;

    // Accept-Ranges header name
    private static final String ACCEPT_RANGES_HEADER = "Accept-Ranges";

    // Accept-Ranges header value
    private static final String ACCEPT_RANGES_BYTES = "bytes";

    /**
     * Full range marker.
     */
    private static ArrayList<Range> FULL = new ArrayList<>(0);

    static final int IO_BUFFER_SIZE = 2048;

    /** default log */
    private final Logger log = LoggerFactory.getLogger(getClass());

    private boolean index;

    private String[] indexFiles;

	private ServletContext context;

    public StreamRenderer(boolean index, String[] indexFiles,ServletContext context) {
        this.index = index;
        this.indexFiles = indexFiles;
        this.context = context;
    }

    public void render(SlingHttpServletRequest request,
            SlingHttpServletResponse response) throws IOException {
    	
        // whether this servlet is called as of a request include
        final boolean included = request.getAttribute(SlingConstants.ATTR_REQUEST_SERVLET) != null;

        // ensure no extension or "res"
        String ext = request.getRequestPathInfo().getExtension();
        if (ext != null && !ext.equals(DefaultGetServlet.EXT_RES)) {
            request.getRequestProgressTracker().log(
                "StreamRendererServlet does not support for extension " + ext);
            if (included || response.isCommitted()) {
                log.error(
                    "StreamRendererServlet does not support extension {}",
                    ext);
            } else {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
            }
            return;
        }

        Resource resource = request.getResource();

        if (ResourceUtil.isNonExistingResource(resource)) {
            throw new ResourceNotFoundException("No data to render.");
        }
        // trailing slash on url means directory listing

        if ("/".equals(request.getRequestPathInfo().getSuffix())) {
            renderDirectory(request, response, included);
            return;
        }

        // check the last modification time and If-Modified-Since header
        if (!included) {
            ResourceMetadata meta = resource.getResourceMetadata();
            long modifTime = meta.getModificationTime();
            if (unmodified(request, modifTime)) {
                response.setStatus(SC_NOT_MODIFIED);
                return;
            }
        }

        // fall back to plain text rendering if the resource has no stream
        if (resource.getResourceType().equals(JcrConstants.NT_LINKEDFILE)) {
            final ValueMap vm = resource.adaptTo(ValueMap.class);
            final String actualResourcePath = vm.get(JcrConstants.JCR_CONTENT, String.class);
            resource = request.getResourceResolver().getResource(actualResourcePath);
        }
        InputStream stream = resource.adaptTo(InputStream.class);
        if (stream != null) {
            if ( stream instanceof ExternalizableInputStream) {
                response.sendRedirect(((ExternalizableInputStream)stream).getURI().toString());
                return;
            }
            if (isHeadRequest(request)) {
                setContentLength(response, resource.getResourceMetadata().getContentLength());
                setHeaders(resource, response);
                return;
            }

            streamResource(resource, stream, included, request, response);

        } else {

            // the resource is the root, do not redirect, immediately index
            if (isRootResourceRequest(resource)) {

                renderDirectory(request, response, included);

            } else if (included || response.isCommitted() ) {

                // request is included or committed, not redirecting
                request.getRequestProgressTracker().log(
                    "StreamRendererServlet: Not redirecting with trailing slash, response is committed or request included");
                log.warn("StreamRendererServlet: Not redirecting with trailing slash, response is committed or request included");

            } else {

                // redirect to this with trailing slash to render the index
                String url = request.getResourceResolver().map(request,
                    resource.getPath())
                    + "/";
                response.sendRedirect(url);

            }
        }
    }

    private boolean isRootResourceRequest(Resource resource) {
        return ("/".equals(resource.getPath())) ||
            ("/".equals(resource.getResourceResolver().map(resource.getPath())));
    }

    private boolean isHeadRequest(HttpServletRequest request) {
        return HttpConstants.METHOD_HEAD.equals(request.getMethod());
    }

    /**
     * Returns <code>true</code> if the request has a
     * <code>If-Modified-Since</code> header whose date value is later than the
     * last modification time given as <code>modifTime</code>.
     *
     * @param request The <code>ComponentRequest</code> checked for the
     *            <code>If-Modified-Since</code> header.
     * @param modifTime The last modification time to compare the header to.
     * @return <code>true</code> if the <code>modifTime</code> is less than or
     *         equal to the time of the <code>If-Modified-Since</code> header.
     */
    private boolean unmodified(HttpServletRequest request, long modifTime) {
        if (modifTime > 0) {
            long modTime = modifTime / 1000; // seconds
            long ims = request.getDateHeader(HEADER_IF_MODIFIED_SINCE) / 1000;
            return modTime <= ims;
        }

        // we have no modification time value, assume modified
        return false;
    }

    private void streamResource(final Resource resource,
            final InputStream stream, final boolean included,
            final SlingHttpServletRequest request,
            final SlingHttpServletResponse response) throws IOException {
        // finally stream the resource
        try {

            final ArrayList<Range> ranges;
            if (included) {
                // no range support on included requests
                ranges = FULL;

            } else {
                // parse optional ranges
                ranges = parseRange(request, response,
                    resource.getResourceMetadata());
                if (ranges == null) {
                    // there was something wrong, the parseRange has sent a
                    // response and we are done
                    return;
                }

                // set various response headers, unless the request is included
                setHeaders(resource, response);
            }

            ServletOutputStream out = response.getOutputStream();

            if (ranges == FULL) {
                // return full resource
                setContentLength(response,
                    resource.getResourceMetadata().getContentLength());
                byte[] buf = new byte[IO_BUFFER_SIZE];
                int rd;
                while ((rd = stream.read(buf)) >= 0) {
                    out.write(buf, 0, rd);
                }
            } else {
                // return ranges of the resource
                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

                if (ranges.size() == 1) {
                    Range range = ranges.get(0);
                    response.addHeader("Content-Range", "bytes " + range.start
                        + "-" + range.end + "/" + range.length);
                    setContentLength(response, range.end - range.start + 1);
                    copy(stream, out, range);
                } else {

                    response.setContentType("multipart/byteranges; boundary="
                        + mimeSeparation);

                    copy(resource, out, ranges.iterator());
                }

            }

        } finally {
            closeSilently(stream);
        }
    }

    private void renderDirectory(final SlingHttpServletRequest request,
            final SlingHttpServletResponse response, final boolean included)
            throws IOException {

        // request is included or committed, not rendering index
        if (included || response.isCommitted()) {
            request.getRequestProgressTracker().log(
                "StreamRendererServlet: Not rendering index, response is committed or request included");
            log.warn("StreamRendererServlet: Not rendering index, response is committed or request included");
            return;
        }

        Resource resource = request.getResource();
        ResourceResolver resolver = request.getResourceResolver();

        // check for an index file
        for (String index : indexFiles) {
            Resource fileRes = resolver.getResource(resource, index);
            if (fileRes != null && !ResourceUtil.isSyntheticResource(fileRes)) {

                setHeaders(fileRes, response);

                if (isHeadRequest(request)) {
                    return;
                }

                // include the index resource with no suffix and selectors !
                RequestDispatcherOptions rdo = new RequestDispatcherOptions();
                rdo.setReplaceSuffix("");
                rdo.setReplaceSelectors("");

                RequestDispatcher dispatcher;
                if (index.indexOf('.') < 0) {
                    String filePath = fileRes.getPath() + ".html";
                    dispatcher = request.getRequestDispatcher(filePath, rdo);
                } else {
                    dispatcher = request.getRequestDispatcher(fileRes, rdo);
                }

                try {
					dispatcher.include(request, response);
				} catch (ServletException e) {
					throw new IOException(e);
				}
                return;
            }
        }

        if (index) {
            if (isHeadRequest(request)) {
                setHeaders(resource, response);
                return;
            }
            renderIndex(resource, response);
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
        }

    }

    /**
     * @param resource
     * @param response
     */
    private void setHeaders(Resource resource,
            SlingHttpServletResponse response) {

        final ResourceMetadata meta = resource.getResourceMetadata();
        final long modifTime = meta.getModificationTime();
        if (modifTime > 0) {
            response.setDateHeader(HEADER_LAST_MODIFIED, modifTime);
        }

        final String defaultContentType = "application/octet-stream";
        String contentType = meta.getContentType();
        if (contentType == null || defaultContentType.equals(contentType)) {
            // if repository doesn't provide a content-type, or
            // provides the
            // default one,
            // try to do better using our servlet context
            final String ct = context.getMimeType(
                resource.getPath());
            if (ct != null) {
                contentType = ct;
            }
        }

        if (contentType == null) {
            contentType = defaultContentType;
        }

        response.setContentType(contentType);

        String encoding = meta.getCharacterEncoding();
        if (encoding != null) {
            response.setCharacterEncoding(encoding);
        }

        // announce support for ranges if we know the size to be larger than 100KB
        if (meta.getContentLength() > ACCEPT_RANGES_THRESHOLD) {
            response.setHeader(ACCEPT_RANGES_HEADER, ACCEPT_RANGES_BYTES);
        }
    }

    /**
     * Set the <code>Content-Length</code> header to the give value. If the
     * length is larger than <code>Integer.MAX_VALUE</code> it is converted to a
     * string and the <code>setHeader(String, String)</code> method is called
     * instead of the <code>setContentLength(int)</code> method.
     *
     * @param response The response on which to set the
     *            <code>Content-Length</code> header.
     * @param length The content length to be set. If this value is equal to or
     *            less than zero, the header is not set.
     */
    private void setContentLength(final HttpServletResponse response, final long length) {
        if (length > 0) {
            if (length < Integer.MAX_VALUE) {
                response.setContentLength((int) length);
            } else {
                response.setHeader("Content-Length", String.valueOf(length));
            }
        }
    }

    private void renderIndex(Resource resource,
            SlingHttpServletResponse response) throws IOException {

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");

        String path = resource.getPath();

        PrintWriter pw = response.getWriter();
        pw.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">");
        pw.println("<html>");
        pw.println("<head>");
        pw.println("<title>Index of " + path + "</title>");
        pw.println("</head>");

        pw.println("<body>");
        pw.println("<h1>Index of " + path + "</h1>");

        pw.println("<pre>");
        pw.println("Name                               Last modified                   Size  Description");
        pw.println("<hr>");

        if (!"/".equals(path)) {
            pw.println("<a href='../'>../</a>                                                                 -     Parent");
        }

        // render the children
        Iterator<Resource> children = resource.listChildren();
        while (children.hasNext()) {
            renderChild(pw, children.next());
        }

        pw.println("</pre>");
        pw.println("</body>");
        pw.println("</html>");

    }

    private void renderChild(PrintWriter pw, Resource resource) {

        String name = ResourceUtil.getName(resource.getPath());

        InputStream ins = resource.adaptTo(InputStream.class);
        if (ins == null) {
            name += "/";
        } else {
            closeSilently(ins);
        }

        String displayName = name;
        String suffix;
        if (displayName.length() >= 32) {
            displayName = displayName.substring(0, 29) + "...";
            suffix = "";
        } else {
            suffix = "                                               ".substring(
                0, 32 - displayName.length());
        }
        pw.printf("<a href='%s'>%s</a>%s", name, displayName, suffix);

        ResourceMetadata meta = resource.getResourceMetadata();
        long lastModified = meta.getModificationTime();
        pw.print("    " + new Date(lastModified) + "    ");

        long length = meta.getContentLength();
        if (length > 0) {
            pw.print(length);
        } else {
            pw.print('-');
        }

        pw.println();
    }

    //---------- Range header support
    // The following code is copy-derived from the Tomcate DefaultServlet
    // http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?view=markup

    /**
     * Copies a number of ranges from the given resource to the output stream.
     * Copy the contents of the specified input stream to the specified output
     * stream, and ensure that both streams are closed before returning (even in
     * the face of an exception).
     *
     * @param resource The resource from which to send ranges
     * @param ostream The output stream to write to
     * @param ranges Iterator of the ranges the client wanted to retrieve
     * @exception IOException if an input/output error occurs
     */
    private void copy(Resource resource, ServletOutputStream ostream,
            Iterator<Range> ranges) throws IOException {

        String contentType = resource.getResourceMetadata().getContentType();
        IOException exception = null;

        while ((exception == null) && (ranges.hasNext())) {

            InputStream resourceInputStream = resource.adaptTo(InputStream.class);
            InputStream istream = new BufferedInputStream(resourceInputStream,
                IO_BUFFER_SIZE);

            try {
                Range currentRange = ranges.next();

                // Writing MIME header.
                ostream.println();
                ostream.println("--" + mimeSeparation);
                if (contentType != null) {
                    ostream.println("Content-Type: " + contentType);
                }
                ostream.println("Content-Range: bytes " + currentRange.start + "-"
                    + currentRange.end + "/" + currentRange.length);
                ostream.println();

                // Copy content
                try {
                    copy(istream, ostream, currentRange);
                } catch(IOException e) {
                    exception = e;
                }
            } finally {
                closeSilently(istream);
            }

        }

        ostream.println();
        ostream.print("--" + mimeSeparation + "--");

        if(exception != null) {
            throw exception;
        }
    }

    /**
    * Copy the contents of the specified input stream to the specified
    * output stream.
    *
    * @param istream The input stream to read from
    * @param ostream The output stream to write to
    * @param range Range the client wanted to retrieve
    * @exception IOException if an input/output error occurs
    */
    private void copy(InputStream istream, OutputStream ostream,
            Range range) throws IOException {
        // HTTP Range 0-9 means "byte 9 included"
        final long endIndex = range.end + 1;
        log.debug("copy: Serving bytes: {}-{}", range.start, endIndex);
        staticCopyRange(istream, ostream, range.start, endIndex);
    }

    // static, package-private method to make unit testing easier
    static void staticCopyRange(InputStream istream,
            OutputStream ostream, long start, long end) throws IOException {
        long position = 0;
        byte buffer[] = new byte[IO_BUFFER_SIZE];

        while (position < start) {
            long skipped = istream.skip(start - position);
            if (skipped == 0) {
                // skip() may return zero if for whatever reason it wasn't
                // able to advance the stream. In such cases we need to
                // fall back to read() to force the skipping of bytes.
                int len = (int) Math.min(start - position, buffer.length);
                skipped = istream.read(buffer, 0, len);
                if (skipped == -1) {
                    throw new IOException("Failed to skip " + start
                            + " bytes; only skipped " + position + " bytes");
                }
            }
            position += skipped;
        }

        while (position < end) {
            int len = (int) Math.min(end - position, buffer.length);
            int read = istream.read(buffer, 0, len);
            if (read != -1) {
                position += read;
                ostream.write(buffer, 0, read);
            } else {
                break;
            }
        }
    }

    /**
     * Parse the range header.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @return ArrayList of ranges parsed from the Range header or {@link #FULL}
     *         if the full resource should be returned or <code>null</code> if
     *         an error occurred parsing the header and the request has been
     *         finished sending an error status.
     */
    private ArrayList<Range> parseRange(HttpServletRequest request,
            HttpServletResponse response, ResourceMetadata metadata)
            throws IOException {

        // Checking If-Range
        String headerValue = request.getHeader("If-Range");
        if (headerValue != null) {

            long headerValueTime = (-1L);
            try {
                headerValueTime = request.getDateHeader("If-Range");
            } catch (IllegalArgumentException e) {
                // Ignore
            }

            if (headerValueTime == (-1L)) {

                // If the ETag the client gave does not match the entity
                // etag, then the entire entity is returned.
                // Sling: no etag support yet, return full range
                return FULL;

            } else if (metadata.getModificationTime() > (headerValueTime + 1000)) {

                // If the timestamp of the entity the client got is older than
                // the last modification date of the entity, the entire entity
                // is returned.
                return FULL;

            }

        }

        long fileLength = metadata.getContentLength();
        if (fileLength == 0) {
            return FULL;
        }

        // Retrieving the range header (if any is specified)
        String rangeHeader = request.getHeader("Range");
        if (rangeHeader == null) {
            return FULL;
        }

        // bytes is the only range unit supported (and I don't see the point
        // of adding new ones).
        if (!rangeHeader.startsWith("bytes")) {
            failParseRange(response, fileLength, rangeHeader);
            return null;
        }

        rangeHeader = rangeHeader.substring(6);

        // Vector which will contain all the ranges which are successfully
        // parsed.
        ArrayList<Range> result = new ArrayList<>();
        StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ",");

        // Parsing the range list
        while (commaTokenizer.hasMoreTokens()) {
            String rangeDefinition = commaTokenizer.nextToken().trim();

            Range currentRange = new Range();
            currentRange.length = fileLength;

            int dashPos = rangeDefinition.indexOf('-');

            if (dashPos == -1) {
                failParseRange(response, fileLength, rangeHeader);
                return null;
            }

            if (dashPos == 0) {

                try {
                    long offset = Long.parseLong(rangeDefinition);
                    currentRange.start = fileLength + offset;
                    currentRange.end = fileLength - 1;
                } catch (NumberFormatException e) {
                    failParseRange(response, fileLength, rangeHeader);
                    return null;
                }

            } else {

                try {
                    currentRange.start = Long.parseLong(rangeDefinition.substring(
                        0, dashPos));
                    if (dashPos < rangeDefinition.length() - 1)
                        currentRange.end = Long.parseLong(rangeDefinition.substring(
                            dashPos + 1, rangeDefinition.length()));
                    else
                        currentRange.end = fileLength - 1;
                } catch (NumberFormatException e) {
                    failParseRange(response, fileLength, rangeHeader);
                    return null;
                }

            }

            if (!currentRange.validate()) {
                failParseRange(response, fileLength, rangeHeader);
                return null;
            }

            result.add(currentRange);
        }

        return result;
    }

    /**
     * Sends a 416 error response to the client if the Range header is
     * not acceptable
     */
    private void failParseRange(final HttpServletResponse response,
            final long fileLength, final String rangeHeader) throws IOException {
        log.error("parseRange: Cannot support range {}; sending 416",
            rangeHeader);
        response.addHeader("Content-Range", "bytes */" + fileLength);
        response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
    }

    private void closeSilently(final Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException ignore) {
            }
        }
    }

    // --------- Range Inner Class

    protected class Range {

        public long start;

        public long end;

        public long length;

        /**
         * Validate range.
         *
         * @return {@code true} if the range is valid, {@code false} otherwise
         */
        public boolean validate() {
            if (end >= length) end = length - 1;
            return ((start >= 0) && (end >= 0) && (start <= end) && (length > 0));
        }

    }
}
