/*
 * 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.io.PrintWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import javax.json.Json;
import javax.json.JsonException;
import javax.json.stream.JsonGenerator;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.ResponseUtil;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;

/**
 * The <code>SlingInfoServlet</code>
 */
@SuppressWarnings("serial")
@Component(service = Servlet.class,
    property = {
            "service.description=Sling Info Servlet",
            "service.vendor=The Apache Software Foundation",
            "sling.servlet.paths=/system/sling/info"
    })
public class SlingInfoServlet extends SlingSafeMethodsServlet {

    private static final String CACHE_CONTROL_HEADER = "Cache-Control";

    private static final String CACHE_CONTROL_HEADER_VALUE =
        "private, no-store, no-cache, max-age=0, must-revalidate";

    static final String PROVIDER_LABEL = "sessionInfo";

    private Map<String, String> getInfo(final SlingHttpServletRequest request) {
        final Map<String, String> result = new HashMap<>();

        final ResourceResolver resolver = request.getResourceResolver();

        result.put("userID", resolver.getUserID());

        if (request.getAuthType() != null) {
            result.put("authType", request.getAuthType());
        }

        return result;
    }

    @Override
    protected void doGet(final SlingHttpServletRequest request,
            final SlingHttpServletResponse response) throws IOException {

        Map<String, String> data = null;

        if (request.getRequestPathInfo().getSelectors().length > 0) {
            final String label = request.getRequestPathInfo().getSelectors()[0];
            if ( PROVIDER_LABEL.equals(label) ) {
                data = this.getInfo(request);
            }
        }

        if (data == null) {

            response.sendError(HttpServletResponse.SC_NOT_FOUND,
                "Unknown Info Request");

        } else {
            response.setHeader(CACHE_CONTROL_HEADER, CACHE_CONTROL_HEADER_VALUE);

            final String extension = request.getRequestPathInfo().getExtension();
            if ("json".equals(extension)) {
                renderJson(response, data);
            } else if ("txt".equals(extension)) {
                renderPlainText(response, data);
            } else { // default to html
                renderHtml(response, data);
            }

        }
    }

    private void renderJson(final SlingHttpServletResponse response,
            final Map<String, String> data) throws IOException {
        // render data in JSON format
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

        final Writer out = response.getWriter();
        try (JsonGenerator w = Json.createGenerator(out)){
            w.writeStartObject();
            for (final Map.Entry<String, String> e : data.entrySet()) {
                w.write(e.getKey(), e.getValue());
            }
            w.writeEnd();
        } catch (JsonException jse) {
            out.write(jse.toString());
        } finally {
            out.flush();
        }
    }

    private void renderHtml(final SlingHttpServletResponse response,
            final Map<String, String> data) throws IOException {
        // render data in JSON format
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");

        final PrintWriter out = response.getWriter();

        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
        out.println("<html><head><title>Apche Sling Info</title></head>");
        out.println("<body><h1>Apache Sling Info</h1>");

        out.println("<table>");
        for (final Map.Entry<String, String> e : data.entrySet()) {
            out.print("<tr><td>");
            out.print(ResponseUtil.escapeXml(e.getKey()));
            out.print("</td><td>");
            out.print(ResponseUtil.escapeXml(e.getValue()));
            out.println("</td></tr>");
        }
        out.println("</table>");

        out.println("</body>");
        out.flush();
    }

    private void renderPlainText(final SlingHttpServletResponse response,
            final Map<String, String> data) throws IOException {

        // render data in JSON format
        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");

        final PrintWriter out = response.getWriter();

        for (final Map.Entry<String, String> e : data.entrySet()) {
            out.print(e.getKey());
            out.print(": ");
            out.println(e.getValue());
        }

        out.flush();
    }
}