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

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import javax.jcr.version.VersionManager;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.servlet.Servlet;
import javax.servlet.ServletException;

import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.get.impl.util.JsonObjectCreator;
import org.apache.sling.servlets.get.impl.util.JsonRenderer;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

/**
 * The <code>VersionInfoServlet</code> renders list of versions available for
 * the current resource.
 *
 * At the moment only JCR nodes are supported.
 */
@Component(name="org.apache.sling.servlets.get.impl.version.VersionInfoServlet",
           configurationPolicy=ConfigurationPolicy.REQUIRE,
           service = Servlet.class,
           property = {
                    "service.description=Version info servlet",
                    "service.vendor=The Apache Software Foundation",
                    "sling.servlet.resourceTypes=sling/servlet/default",
                    "sling.servlet.methods=GET",
                    "sling.servlet.selectors=V",
                    "sling.servlet.extensions=json"
           })
@Designate(ocd = VersionInfoServlet.Config.class)
public class VersionInfoServlet extends SlingSafeMethodsServlet {

    @ObjectClassDefinition(name = "Apache Sling Version Info Servlet",
            description = "The Sling Version Info Servlet renders list of versions available for the current resource")
    public @interface Config {

        @AttributeDefinition(name = "Selector", description="List of selectors this servlet handles to display the versions")
        String[] sling_servlet_selectors() default "V";
    }
    private static final long serialVersionUID = 1656887064561951302L;

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

    @Override
    public void doGet(SlingHttpServletRequest req, SlingHttpServletResponse resp) throws ServletException,
            IOException {
        resp.setContentType(req.getResponseContentType());
        resp.setCharacterEncoding("UTF-8");
        final boolean tidy = hasSelector(req, TIDY);
        final boolean harray = hasSelector(req, HARRAY);

        final JsonRenderer.Options opt = renderer.options().withIndent(tidy ? INDENT_SPACES : 0)
                    .withArraysForChildren(harray);
        
        try {
        	VersionManager vm = req.getResourceResolver().adaptTo(Session.class).getWorkspace().getVersionManager();
            resp.getWriter().write(renderer.prettyPrint(getJsonObject(req.getResource(), vm), opt));
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }

    private JsonObject getJsonObject(Resource resource, VersionManager vm) throws RepositoryException {
        final JsonObjectBuilder result = Json.createObjectBuilder();
        final Node node = resource.adaptTo(Node.class);
        if (node == null || !node.isNodeType(JcrConstants.MIX_VERSIONABLE)) {
            return result.build();
        }
        final String absPath = resource.getPath();
        final VersionHistory history = vm.getVersionHistory(absPath);
        final Version baseVersion = vm.getBaseVersion(absPath);
        
        for (final VersionIterator it = history.getAllVersions(); it.hasNext();) {
            final Version v = it.nextVersion();
            final JsonObjectBuilder obj = Json.createObjectBuilder();
            obj.add("created", createdDate(v));
            obj.add("successors", getArrayBuilder(getNames(v.getSuccessors())));
            obj.add("predecessors", getArrayBuilder(getNames(v.getPredecessors())));
            
            obj.add("labels", getArrayBuilder(history.getVersionLabels(v)));
            obj.add("baseVersion", baseVersion.isSame(v));
            result.add(v.getName(), obj);
        }

        return Json.createObjectBuilder().add("versions", result).build();
    }
    
    private JsonArrayBuilder getArrayBuilder(String[] values) {
        JsonArrayBuilder builder = Json.createArrayBuilder();
        
        for (String value : values) {
            builder.add(value);
        }
        
        return builder;
    }
    
    private JsonArrayBuilder getArrayBuilder(Collection<String> values) {
        JsonArrayBuilder builder = Json.createArrayBuilder();
        
        for (String value : values) {
            builder.add(value);
        }
        
        return builder;
    }

    private static Collection<String> getNames(Version[] versions) throws RepositoryException {
        final List<String> result = new ArrayList<>();
        for (Version s : versions) {
            result.add(s.getName());
        }
        return result;
    }

    /** True if our request has the given selector */
    private boolean hasSelector(SlingHttpServletRequest req, String selectorToCheck) {
        for (String selector : req.getRequestPathInfo().getSelectors()) {
            if (selectorToCheck.equals(selector)) {
                return true;
            }
        }
        return false;
    }

    private static String createdDate(Node node) throws RepositoryException {
        return JsonObjectCreator.format(node.getProperty(JcrConstants.JCR_CREATED).getDate());
    }

}
