/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ 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.xss.impl.webconsole;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonWriter;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.sling.xss.XSSFilter;
import org.apache.sling.xss.impl.XSSFilterImpl;
import org.apache.sling.xss.impl.status.XSSStatusService;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(
        service = Servlet.class,
        property = {
                XSSProtectionAPIWebConsolePlugin.REG_PROP_LABEL + "=" + XSSProtectionAPIWebConsolePlugin.LABEL,
                XSSProtectionAPIWebConsolePlugin.REG_PROP_TITLE + "=" + XSSProtectionAPIWebConsolePlugin.TITLE,
                XSSProtectionAPIWebConsolePlugin.REG_PROP_CATEGORY + "=Sling"
        }
)
public class XSSProtectionAPIWebConsolePlugin extends HttpServlet {

    private static final Logger LOGGER = LoggerFactory.getLogger(XSSProtectionAPIWebConsolePlugin.class);
    /*
        do not replace the following constants with the ones from org.apache.felix, since you'll create a wiring to those APIs; the
        current way this plugin is written allows it to optionally be available, if the Felix Web Console is installed on the OSGi
        platform where this bundle will be deployed
     */
    static final String REG_PROP_LABEL = "felix.webconsole.label";
    static final String REG_PROP_TITLE = "felix.webconsole.title";
    static final String REG_PROP_CATEGORY = "felix.webconsole.category";
    static final String LABEL = "xssprotection";
    static final String TITLE= "XSS Protection";

    private static final String PLUGIN_ROOT_PATH = "/" + LABEL;
    private static final String URI_CONFIG_XHR = PLUGIN_ROOT_PATH + "/config.xhr";
    private static final String URI_BLOCKED_XHR = PLUGIN_ROOT_PATH + "/blocked.json";
    private static final String URI_CONFIG_XML = PLUGIN_ROOT_PATH + "/config.xml";
    private static final String INTERNAL_RESOURCES_FOLDER = "/webconsole";
    private static final String RES_ROOT = PLUGIN_ROOT_PATH + INTERNAL_RESOURCES_FOLDER;
    private static final String RES_URI_PRETTIFY_CSS = RES_ROOT + "/prettify.css";
    private static final String RES_URI_PRETTIFY_JS = RES_ROOT + "/prettify.js";
    private static final String RES_URI_XSS_CSS = RES_ROOT + "/xss.css";
    private static final String RES_URI_XSS_JS = RES_ROOT + "/xss.js";
    private static final String RES_URI_BLOCKED_JS = RES_ROOT + "/blocked.js";
    private static final String RES_URI_CONFIG_JS = RES_ROOT + "/config.js";
    public static final String SCRIPT_TAG = "<script src='%s'></script>\n";
    public static final String LINK_TAG = "<link rel='stylesheet' type='text/css' href='%s'>";

    @Reference(target = "(component.name=org.apache.sling.xss.impl.XSSFilterImpl)")
    private XSSFilter xssFilter;

    @Reference
    private XSSStatusService statusService;

    private static final Set<String> CSS_RESOURCES = new HashSet<>(Arrays.asList(RES_URI_PRETTIFY_CSS, RES_URI_XSS_CSS));
    private static final Set<String> JS_RESOURCES = new HashSet<>(Arrays.asList(RES_URI_PRETTIFY_JS, RES_URI_XSS_JS, RES_URI_BLOCKED_JS,
            RES_URI_CONFIG_JS));

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        String pluginResource = request.getPathInfo();
        String consoleRoot = request.getRequestURI().substring(0, request.getRequestURI().indexOf(pluginResource));
        if (CSS_RESOURCES.contains(pluginResource)) {
            streamResource(response, FilenameUtils.getName(pluginResource), "text/css");
        } else if (JS_RESOURCES.contains(pluginResource)) {
            streamResource(response, FilenameUtils.getName(pluginResource), "application/javascript");
        } else if (URI_CONFIG_XHR.equalsIgnoreCase(pluginResource) && xssFilter != null) {
            writeAntiSamyConfiguration(consoleRoot, response);
        } else if (URI_CONFIG_XML.equalsIgnoreCase(pluginResource) && xssFilter != null) {
            streamAntiSamyConfiguration(response);
        } else if (URI_BLOCKED_XHR.equalsIgnoreCase(pluginResource)) {
            generateInvalidUrlsJSONReport(response);
        } else {
            try {
                PrintWriter printWriter = response.getWriter();
                printWriter.printf(LINK_TAG, consoleRoot + RES_URI_XSS_CSS);
                printWriter.printf(SCRIPT_TAG, consoleRoot + RES_URI_XSS_JS);
                printWriter.println("<div id='xss-tabs'>");
                printWriter.println("<ul>");
                printWriter.println("<li id='blocked-tab'><a href='#blocked'><span>Status</span></a></li>");
                if (xssFilter != null) {
                    printWriter.println(
                            String.format("<li id='config-tab'><a href='%s'><span>Active Configuration</span></a></li>",
                                    consoleRoot + URI_CONFIG_XHR));
                }
                printWriter.println("</ul>");
                printWriter.println("<div id='blocked'>");
                printWriter.println("<div class='table'>");
                printWriter.println("<div class='ui-widget-header ui-corner-top buttonGroup'>Blocked URLs</div>");
                printWriter.println("<table class='nicetable tablesorter' id='invalid-urls'>");
                printWriter.println("<thead>");
                printWriter.println("<tr>");
                printWriter.println("<th class='header'>URL</th>");
                printWriter.println("<th class='header'>Times Blocked</th>");
                printWriter.println("</tr>");
                printWriter.println("</thead>");
                printWriter.println("<tbody id='invalid-urls-rows'>");
                printWriter.println("</tbody>");
                printWriter.println("</table>");
                printWriter.println("</div></div></div>");
            } catch (IOException e) {
                LOGGER.error("Unable to generate scaffold for the webconsole plugin output.", e);
            }
        }
    }

    private void streamAntiSamyConfiguration(HttpServletResponse response) {
        try {
            response.setContentType("application/xml");
            response.setHeader("Content-Disposition", "attachment; filename=config.xml");
            XSSFilterImpl xssFilterImpl = (XSSFilterImpl) xssFilter;
            IOUtils.copy(xssFilterImpl.getActivePolicy().read(), response.getOutputStream());
        } catch (IOException e) {
            LOGGER.error("Unable to stream AntiSamy configuration.", e);
        }

    }

    private void generateInvalidUrlsJSONReport(HttpServletResponse response) {
        JsonArrayBuilder hrefs = Json.createArrayBuilder();
        for (Map.Entry<String, AtomicInteger> entry : statusService.getInvalidUrls().entrySet()) {
            JsonObject href =
                    Json.createObjectBuilder().add("href", entry.getKey()).add("times", entry.getValue().intValue()).build();
            hrefs.add(href);
        }
        try (JsonWriter writer = Json.createWriter(response.getWriter())) {
            response.setContentType("application/json");
            writer.writeObject(Json.createObjectBuilder().add("hrefs", hrefs.build()).build());
        } catch (IOException e) {
            LOGGER.error("Unable to write JSON report for invalid URLs.", e);
        }

    }

    private void writeAntiSamyConfiguration(String consoleRoot, HttpServletResponse response) {
        response.setContentType("text/html");
        XSSFilterImpl xssFilterImpl = (XSSFilterImpl) xssFilter;
        XSSFilterImpl.AntiSamyPolicy antiSamyPolicy = xssFilterImpl.getActivePolicy();
        if (antiSamyPolicy != null) {
            try {
                PrintWriter printWriter = response.getWriter();
                printWriter.printf(SCRIPT_TAG, consoleRoot + RES_URI_CONFIG_JS);
                printWriter.write("<div id='config'>");
                printWriter.printf(LINK_TAG, consoleRoot + RES_URI_PRETTIFY_CSS);
                printWriter.printf(SCRIPT_TAG, consoleRoot + RES_URI_PRETTIFY_JS);
                printWriter.write("<p class='statline ui-state-highlight'>The current AntiSamy configuration ");
                if (antiSamyPolicy.isEmbedded()) {
                    printWriter.write("is the default one embedded in the org.apache.sling.xss bundle.");
                } else {
                    printWriter.printf("is loaded from %s.", antiSamyPolicy.getPath());
                }
                printWriter.write("<button style='float:right' type='button' id='download-config'>Download</button></p>");
                String contents = "";
                try (InputStream configurationStream = antiSamyPolicy.read()) {
                    contents = IOUtils.toString(configurationStream, StandardCharsets.UTF_8);
                }
                printWriter.write("<pre class='prettyprint linenums'>");
                printWriter.write(StringEscapeUtils.escapeHtml4(contents));
                printWriter.write("</pre>");
                printWriter.write("</div>");
            } catch (IOException e) {
                LOGGER.error("Unable to write the AntiSamy configuration tab.", e);
            }
        }
    }

    /**
     * Streams a resource embedded in the bundle.
     * @param response the response
     * @param file the file name
     * @param contentType the content type of the resource
     */
    private void streamResource(HttpServletResponse response, String file, String contentType) {
        try (InputStream cssStream =
                     getClass().getClassLoader().getResourceAsStream(INTERNAL_RESOURCES_FOLDER + "/" + file)) {
            if (cssStream != null) {
                response.setContentType(contentType);
                IOUtils.copy(cssStream, response.getOutputStream());
            }
        } catch (IOException e) {
            LOGGER.error(String.format("Unable to stream bundled resource %s.", file), e);
        }
    }
}
