/*
 * 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;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.SlingConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceNotFoundException;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.get.impl.helpers.HeadServletResponse;
import org.apache.sling.servlets.get.impl.helpers.HtmlRenderer;
import org.apache.sling.servlets.get.impl.helpers.JsonRenderer;
import org.apache.sling.servlets.get.impl.helpers.PlainTextRenderer;
import org.apache.sling.servlets.get.impl.helpers.Renderer;
import org.apache.sling.servlets.get.impl.helpers.StreamRenderer;
import org.apache.sling.servlets.get.impl.helpers.XMLRenderer;
import org.apache.sling.xss.XSSAPI;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A SlingSafeMethodsServlet that renders the current Resource as simple HTML
 */
@Component(service = Servlet.class,
    name="org.apache.sling.servlets.get.DefaultGetServlet",
    property = {
            "service.description=Default GET Servlet",
            "service.vendor=The Apache Software Foundation",

            // Use this as a default servlet for Sling
            "sling.servlet.resourceTypes=sling/servlet/default",
            "sling.servlet.prefix:Integer=-1",

            // Generic handler for all get requests
            "sling.servlet.methods=GET",
            "sling.servlet.methods=HEAD"
    })
@Designate(ocd=DefaultGetServlet.Config.class)
public class DefaultGetServlet extends SlingSafeMethodsServlet {

    private static final long serialVersionUID = -2714152339750885354L;

    @ObjectClassDefinition(name="Apache Sling GET Servlet",
            description="The Sling GET servlet is registered as the default servlet to handle GET requests.")
    public @interface Config {

        @AttributeDefinition(name = "Extension Aliases",
                description="The aliases can be used to map several extensions to a " +
                            "single servlet. For instance \"xml:pdf,rtf\" maps the extensions \".pdf\" and " +
                            "\".rtf\" to the servlet helper handling the \".xml\" extension.")
        String[] aliases();

        @AttributeDefinition(name = "Auto Index",
                description="Controls whether a simple directory index is rendered for " +
                             "a directory request. A directory request is a request to a resource with a " +
                             "trailing slash (/) character, for example http://host/apps/. If none of the " +
                             "index resources exists, the default GET servlet may automatically render an " +
                             "index listing of the child resources if this option is checked, which is the " +
                             "default. If this option is not checked, the request to the resource is " +
                             "forbidden and results in a status 403/FORBIDDEN. This configuration " +
                             "corresponds to the \"Index\" option of the Options directive of Apache HTTP " +
                             "Server (httpd).")
        boolean index() default false;

        @AttributeDefinition(name = "Index Resources",
                description = "List of child resources to be considered for rendering  " +
                             "the index of a \"directory\". The default value is [ \"index\", \"index.html\" ].  " +
                             "Each entry in the list is checked and the first entry found is included to  " +
                             "render the index. If an entry is selected, which has not extension (for  " +
                             "example the \"index\" resource), the extension \".html\" is appended for the  " +
                             "inclusion to indicate the desired text/html rendering. If the resource name  " +
                             "has an extension (as in \"index.html\"), no additional extension is appended  " +
                             "for the inclusion. This configuration corresponds to the <DirectoryIndex>  " +
                             "directive of Apache HTTP Server (httpd).")
        String[] index_files() default { "index","index.html" };

        @AttributeDefinition(name = "Enable HTML",
                description = "Whether the renderer for HTML of the default GET servlet is enabled or not. By default the HTML renderer is enabled.")
        boolean enable_html() default true;

        @AttributeDefinition(name = "Enable JSON",
                description = "Whether the renderer for JSON of the default GET servlet is enabled or not. By default the JSON renderer is enabled.")
        boolean enable_json() default true;

        @AttributeDefinition(name = "Enable Plain Text",
                description = "Whether the renderer for plain text of the default GET servlet is enabled or not. By default the plain text renderer is enabled.")
        boolean enable_txt() default true;

        @AttributeDefinition(name = "Enable XML",
                description = "Whether the renderer for XML of the default GET servlet is enabled or not. By default the XML renderer is enabled.")
        boolean enable_xml() default true;

        @AttributeDefinition(name = "JSON Max results",
                description = "The maximum number of resources that should " +
                  "be returned when doing a node.5.json or node.infinity.json. In JSON terms " +
                  "this basically means the number of Objects to return. Default value is " +
                  "200.")
        int json_maximumresults() default 200;
    }

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private Map<String, Renderer> rendererMap = new HashMap<>();

    private int jsonMaximumResults;

    /** Additional aliases. */
    private String[] aliases;

    /** Whether to support automatic index rendering */
    private boolean index;

    /** The names of index rendering children */
    private String[] indexFiles;

    private boolean enableHtml;

    private boolean enableTxt;

    private boolean enableJson;

    private boolean enableXml;

    @Reference(policyOption = ReferencePolicyOption.GREEDY)
    private XSSAPI xssApi;
    
    public static final String EXT_HTML = "html";

    public static final String EXT_TXT = "txt";

    public static final String EXT_JSON = "json";

    public static final String EXT_XML = "xml";

    public static final String EXT_RES = "res";

    @Activate
    protected void activate(Config cfg) {
        this.aliases = cfg.aliases();
        this.index = cfg.index();
        this.indexFiles = cfg.index_files();
        if ( this.indexFiles == null ) {
            this.indexFiles = new String[0];
        }

        this.enableHtml = cfg.enable_html();
        this.enableTxt = cfg.enable_txt();
        this.enableJson = cfg.enable_json();
        this.enableXml = cfg.enable_xml();
        this.jsonMaximumResults = cfg.json_maximumresults();
    }

    @Deactivate
    protected void deactivate() {
        this.aliases = null;
        this.index = false;
        this.indexFiles = null;
    }

    private Renderer getDefaultRendererServlet(final String type) {
    	Renderer servlet = null;
        if ( EXT_RES.equals(type) ) {
            servlet = new StreamRenderer(index, indexFiles, getServletContext());
        } else if ( EXT_HTML.equals(type) ) {
            servlet = new HtmlRenderer(xssApi);
        } else if ( EXT_TXT.equals(type) ) {
            servlet = new PlainTextRenderer();
        } else if (EXT_JSON.equals(type) ) {
            servlet = new JsonRenderer(jsonMaximumResults);
        } else if ( EXT_XML.equals(type) ) {
            servlet = new XMLRenderer();
        }
        return servlet;
    }

    @Override
    public void init() throws ServletException {
        super.init();

        // use the servlet for rendering StreamRendererServlet.EXT_RES as the
        // streamer servlet
        Renderer streamerServlet = getDefaultRendererServlet(EXT_RES);

        rendererMap.put(null, streamerServlet);
        
        rendererMap.put(EXT_RES, streamerServlet);
        
        if (enableHtml) {
            rendererMap.put(EXT_HTML,
                    getDefaultRendererServlet(EXT_HTML));
        }

        if (enableTxt) {
            rendererMap.put(EXT_TXT,
                    getDefaultRendererServlet(EXT_TXT));
        }

        if (enableJson) {
            rendererMap.put(EXT_JSON,
                    getDefaultRendererServlet(EXT_JSON));
        }

        if (enableXml) {
            rendererMap.put(EXT_XML,
                    getDefaultRendererServlet(EXT_XML));
        }


        // check additional aliases
        if (this.aliases != null) {
            for (final String m : aliases) {
                final int pos = m.indexOf(':');
                if (pos != -1) {
                    final String type = m.substring(0, pos);
                    Renderer servlet = rendererMap.get(type);
                    if ( servlet == null ) {
                        servlet = getDefaultRendererServlet(type);
                    }
                    if (servlet != null) {
                        final String extensions = m.substring(pos + 1);
                        final StringTokenizer st = new StringTokenizer(
                            extensions, ",");
                        while (st.hasMoreTokens()) {
                            final String ext = st.nextToken();
                            rendererMap.put(ext, servlet);
                        }
                    } else {
                        logger.warn("Unable to enable renderer alias(es) for {} - type not supported", m);
                    }
                }
            }
        }
    }

    /**
     * @throws ResourceNotFoundException if the resource of the request is a non
     *             existing resource.
     */
    @Override
    protected void doGet(SlingHttpServletRequest request,
            SlingHttpServletResponse response) throws ServletException,
            IOException {

        // cannot handle the request for missing resources
        if (ResourceUtil.isNonExistingResource(request.getResource())) {
            throw new ResourceNotFoundException(
                request.getResource().getPath(), "No resource found");
        }

        Renderer rendererServlet;
        String ext = request.getRequestPathInfo().getExtension();
        rendererServlet = rendererMap.get(ext);

        // fail if we should not just stream or we cannot support the ext.
        if (rendererServlet == null) {
            request.getRequestProgressTracker().log(
                "No renderer for extension " + ext);
            // if this is an included request, sendError() would fail
            // as the response is already committed, in this case we just
            // do nothing (but log an error message)
            if (response.isCommitted()
                || request.getAttribute(SlingConstants.ATTR_REQUEST_SERVLET) != null) {
                logger.error(
                    "No renderer for extension {}, cannot render resource {}",
                    ext, request.getResource());
            } else {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
            }
            return;
        }

        request.getRequestProgressTracker().log(
            "Using " + rendererServlet.getClass().getName()
                + " to render for extension=" + ext);
        rendererServlet.render(request, response);
    }

    @Override
    protected void doHead(SlingHttpServletRequest request,
                          SlingHttpServletResponse response) throws ServletException,
            IOException {

        response = new HeadServletResponse(response);
        doGet(request, response);
    }

    @Override
    public void destroy() {
        rendererMap.clear();
        super.destroy();
    }
}
