/*
 * 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.servlets.get.impl.util.JsonToText;
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 JsonRenderer implements Renderer {

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

    /** 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 JsonToText renderer = new JsonToText();

	private boolean ecmaSupport;

    public JsonRenderer(long maximumResults, boolean ecmaSupport) {
        this.maximumResults = maximumResults;
        this.ecmaSupport = ecmaSupport;
    }

    public void render(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, ecmaSupport);
            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 JsonToText.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);
    }
}

