/*
 * 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 java.io.IOException;
import java.io.StringWriter;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
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.util.JsonRenderer;
import org.apache.sling.servlets.get.impl.util.ResourceTraversor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The <code>JsonRendererServlet</code> renders the current resource in JSON
 * on behalf of the {@link org.apache.sling.servlets.get.impl.DefaultGetServlet}.
 */
public class JsonRendererServlet extends SlingSafeMethodsServlet {

    private final Logger log = LoggerFactory.getLogger(JsonRendererServlet.class);

    private static final long serialVersionUID = 5577121546674133317L;

    /** Recursion level selector that means "all levels" */
    public static final String INFINITY = "infinity";

    /** Selector that means "pretty-print the output */
    public static final String TIDY = "tidy";

    /** Selector that causes hierarchy to be rendered as arrays
     *  instead of child objects - useful to preserve the order of those
     *  child objects */
    public static final String HARRAY = "harray";

    /** How much to indent in tidy mode */
    public static final int INDENT_SPACES = 2;

    private long maximumResults;

    private final JsonRenderer renderer = new JsonRenderer();

    public JsonRendererServlet(long maximumResults) {
        this.maximumResults = maximumResults;
    }

    @Override
    protected void doGet(SlingHttpServletRequest req,
            SlingHttpServletResponse resp) throws IOException {
        // Access and check our data
        final Resource r = req.getResource();
        if (ResourceUtil.isNonExistingResource(r)) {
            throw new ResourceNotFoundException("No data to render.");
        }

        int maxRecursionLevels = 0;
        try {
            maxRecursionLevels = getMaxRecursionLevel(req);
        } catch(IllegalArgumentException iae) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, iae.getMessage());
            return;
        }

        resp.setContentType(req.getResponseContentType());
        resp.setCharacterEncoding("UTF-8");

        // We check the tree to see if the nr of nodes isn't bigger than the allowed nr.
        boolean allowDump = true;
        int allowedLevel = 0;
        final boolean tidy = isTidy(req);
        final boolean harray = hasSelector(req, HARRAY);
        ResourceTraversor traversor = null;
        try {
            traversor = new ResourceTraversor(maxRecursionLevels, maximumResults, r);
            allowedLevel = traversor.collectResources();
            if ( allowedLevel != -1 ) {
                allowDump = false;
            }
        } catch (final Exception e) {
            reportException(e);
        }
        try {
            // Dump the resource if we can
            if (allowDump) {
                if (tidy || harray) {
                    final JsonRenderer.Options opt = renderer.options()
                            .withIndent(tidy ? INDENT_SPACES : 0)
                            .withArraysForChildren(harray);
                    resp.getWriter().write(renderer.prettyPrint(traversor.getJSONObject(), opt));
                } else {
                    // If no rendering options, use the plain toString() method, for
                    // backwards compatibility. Output might be slightly different
                    // with prettyPrint and no options
                    StringWriter writer = new StringWriter();
                    Json.createGenerator(writer).write(traversor.getJSONObject()).close();
                    resp.getWriter().write(writer.toString());
                }

            } else {
                // We are not allowed to do the dump.
                // Send a 300 
                String tidyUrl = (tidy) ? "tidy." : "";
                resp.setStatus(HttpServletResponse.SC_MULTIPLE_CHOICES);
                StringWriter writer = new StringWriter();
                JsonGenerator json = Json.createGenerator(writer);
                json.writeStartArray();
                while (allowedLevel >= 0) {
                    json.write(r.getResourceMetadata().getResolutionPath() + "." + tidyUrl + allowedLevel + ".json");
                    allowedLevel--;
                }
                json.writeEnd();
                json.close();
                resp.getWriter().write(writer.toString());
            }
        } catch (Exception je) {
            reportException(je);
        }
    }

    /**
     * Get recursion level from selectors. as per SLING-167: the last selector, if present, gives the recursion level.
     *
     * @param req the request
     * @return the recursion level
     * @throws IllegalArgumentException if the detected selector is not a number
     */
    protected int getMaxRecursionLevel(SlingHttpServletRequest req) throws IllegalArgumentException {
        int maxRecursionLevels = 0;
        final String[] selectors = req.getRequestPathInfo().getSelectors();
        if (selectors != null && selectors.length > 0) {
            final String level = selectors[selectors.length - 1];
            if(!TIDY.equals(level) && !HARRAY.equals(level)) {
                if (INFINITY.equals(level)) {
                    maxRecursionLevels = -1;
                } else {
                    try {
                        maxRecursionLevels = Integer.parseInt(level);
                    } catch (NumberFormatException nfe) {
                        //SLING-2324
                        if (StringUtils.isNumeric(level)){
                            maxRecursionLevels = -1;
                        } else {
                            throw new IllegalArgumentException("Invalid recursion selector value '" + level + "'");
                        }
                    }
                }
            }
        }
        return maxRecursionLevels;
    }

    /**
     * Checks if the provided request contains a certain selector.
     * @param req the request
     * @param selectorToCheck the selector
     * @return {@code true} if the selector is present, {@code false} otherwise
     */
    protected boolean hasSelector(SlingHttpServletRequest req, String selectorToCheck) {
        for(String selector : req.getRequestPathInfo().getSelectors()) {
            if(selectorToCheck.equals(selector)) {
                return true;
            }
        }
        return false;
    }

    /**
     * True if our request wants the "tidy" pretty-printed format
     * @param req the request
     * @return {@code true} if the request contains the {@link #TIDY} selector, {@code false} otherwise
     */
    protected boolean isTidy(SlingHttpServletRequest req) {
        return hasSelector(req, TIDY);
    }

    /**
     * @param e
     * @throws SlingException wrapping the given exception
     */
    private void reportException(Exception e) {
        log.warn("Error in JsonRendererServlet: " + e.toString(), e);
        throw new SlingException(e.toString(), e);
    }
}

