/**
 * 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
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * 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.qpid.server.management.plugin.servlet.rest;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObjectAttribute;
import org.apache.qpid.server.model.ConfiguredObjectAttributeOrStatistic;
import org.apache.qpid.server.model.ConfiguredObjectFinder;
import org.apache.qpid.server.model.ConfiguredObjectOperation;
import org.apache.qpid.server.model.ConfiguredObjectStatistic;
import org.apache.qpid.server.model.ConfiguredSettableAttribute;
import org.apache.qpid.server.model.ManagedContextDefault;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.OperationParameter;

public class ApiDocsServlet extends AbstractServlet
{
    private static final long serialVersionUID = 1L;

    private static final Set<Character> VOWELS = new HashSet<>(Arrays.asList('a','e','i','o','u'));

    public static final Comparator<Class<? extends ConfiguredObject>> CLASS_COMPARATOR =
            Comparator.comparing(Class::getSimpleName);

    private final transient ConcurrentMap<Class<? extends ConfiguredObject>, List<Class<? extends ConfiguredObject>>> _typeSpecialisations = new ConcurrentHashMap<>();

    public ApiDocsServlet()
    {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response,
                         final ConfiguredObject<?> managedObject) throws IOException
    {
        final ConfiguredObjectFinder finder = getConfiguredObjectFinder(managedObject);

        final Class<? extends ConfiguredObject> configuredClass;

        final Class<? extends ConfiguredObject>[] hierarchy;

        final String[] servletPathParts = request.getServletPath().split("/");
        final Model model = managedObject.getModel();
        if (servletPathParts.length < 4)
        {
            configuredClass = null;
            hierarchy = null;
        }
        else
        {
            configuredClass = getConfiguredClass(request, managedObject);
            if (configuredClass == null)
            {
                sendError(response, HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            hierarchy = finder.getHierarchy(configuredClass);
            if (hierarchy == null)
            {
                sendError(response, HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            if (!_typeSpecialisations.containsKey(configuredClass))
            {
                final List<Class<? extends ConfiguredObject>> types =
                        new ArrayList<>(model.getTypeRegistry().getTypeSpecialisations(configuredClass));
                _typeSpecialisations.putIfAbsent(configuredClass, types);
            }
        }
        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);


        final PrintWriter writer = response.getWriter();

        writePreamble(writer);
        writeHead(writer, hierarchy, configuredClass);

        if (hierarchy == null)
        {
            writer.println("<table class=\"api\">");
            writer.println("<thead>");
            writer.println("<tr>");
            writer.println("<th class=\"type\">Type</th>");
            writer.println("<th class=\"path\">Path</th>");
            writer.println("<th class=\"description\">Description</th>");
            writer.println("</tr>");
            writer.println("</thead>");
            writer.println("<tbody>");
            final SortedSet<Class<? extends ConfiguredObject>> managedCategories = new TreeSet<>(CLASS_COMPARATOR);
            managedCategories.addAll(finder.getManagedCategories());
            final String pathStem = "/" + servletPathParts[1] + "/" + (servletPathParts.length == 2 ? "latest" : servletPathParts[2]) + "/";
            for (final Class<? extends ConfiguredObject> category : managedCategories)
            {
                final String path = pathStem + category.getSimpleName().toLowerCase();
                writer.println("<tr>");
                writer.println("<td class=\"type\"><a href=" + path + ">" + category.getSimpleName() + "</a></td>");
                writer.println("<td class=\"path\">" + path + "</td>");
                writer.println("<td class=\"description\">" +
                        category.getAnnotation(ManagedObject.class).description()+"</td>");
                writer.println("</tr>");
            }
            writer.println("</tbody>");
            writer.println("</table>");
        }
        else
        {
            final List<Class<? extends ConfiguredObject>> types = _typeSpecialisations.get(configuredClass);
            writeCategoryDescription(writer, configuredClass);
            writeUsage(writer, request, hierarchy, configuredClass);
            writeTypes(writer, model, types);
            writeAttributes(writer, configuredClass, model, types);
            writeStatistics(writer, configuredClass, model, types);
            writeOperations(writer, configuredClass, model, types);
            writeContext(writer, configuredClass, model, types);
        }

        writeFoot(writer);
    }

    private void writePreamble(final PrintWriter writer)
    {
        writer.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
        writer.println("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
        writer.println("<html>");


    }

    private void writeHead(final PrintWriter writer,
                           final Class<? extends ConfiguredObject>[] hierarchy,
                           final Class<? extends ConfiguredObject> configuredClass)
    {
        writer.println("<head>");
        writer.println("<link rel=\"icon\" type=\"image/png\" href=\"/images/qpid-favicon.png\">");
        writer.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/apidocs.css\">");
        writeTitle(writer, hierarchy, configuredClass);

        writer.println("</head>");
        writer.println("<body>");
    }

    private void writeTitle(final PrintWriter writer,
                            final Class<? extends ConfiguredObject>[] hierarchy,
                            final Class<? extends ConfiguredObject> configuredClass)
    {
        writer.print("<title>");
        if(hierarchy == null)
        {
            writer.print("Qpid API");
        }
        else
        {
            writer.print("Qpid API: " + configuredClass.getSimpleName());
        }
        writer.println("</title>");
    }

    private void writeCategoryDescription(PrintWriter writer,
                                          final Class<? extends ConfiguredObject> configuredClass)
    {
        writer.println("<h1>"+configuredClass.getSimpleName()+"</h1>");
        writer.println(configuredClass.getAnnotation(ManagedObject.class).description());
    }

    private void writeUsage(final PrintWriter writer,
                            final HttpServletRequest request,
                            final Class<? extends ConfiguredObject>[] hierarchy,
                            final Class<? extends ConfiguredObject> configuredClass)
    {
        writer.println("<a name=\"usage\"><h2>Usage</h2></a>");
        writer.println("<table class=\"usage\">");
        writer.println("<tbody>");
        writer.print("<tr><th class=\"operation\">Read</th><td class=\"method\">GET</td><td class=\"path\">" + request.getServletPath()
                .replace("apidocs", "api"));

        for (final Class<? extends ConfiguredObject> category : hierarchy)
        {
            writer.print("[/&lt;" + category.getSimpleName().toLowerCase() + " name or id&gt;");
        }
        for(int i = 0; i < hierarchy.length; i++)
        {
            writer.print("] ");
        }
        writer.println("</td></tr>");

        writer.print("<tr><th class=\"operation\">Update</th><td class=\"method\">PUT or POST</td><td class=\"path\">"
                     + request.getServletPath().replace("apidocs", "api"));
        for (final Class<? extends ConfiguredObject> category : hierarchy)
        {
            writer.print("/&lt;" + category.getSimpleName().toLowerCase() + " name or id&gt;");
        }

        writer.print(
                "<tr><th class=\"operation\">Create</th><td class=\"method\">PUT or POST</td><td class=\"path\">"
                + request.getServletPath().replace("apidocs", "api"));
        for (int i = 0; i < hierarchy.length - 1; i++)
        {
            writer.print("/&lt;" + hierarchy[i].getSimpleName().toLowerCase() + " name or id&gt;");
        }

        writer.print("<tr><th class=\"operation\">Delete</th><td class=\"method\">DELETE</td><td class=\"path\">"
                     + request.getServletPath().replace("apidocs", "api"));
        for (final Class<? extends ConfiguredObject> category : hierarchy)
        {
            writer.print("/&lt;" + category.getSimpleName().toLowerCase() + " name or id&gt;");
        }

        writer.println("</tbody>");
        writer.println("</table>");

    }


    private void writeTypes(final PrintWriter writer,
                            final Model model,
                            final List<Class<? extends ConfiguredObject>> types)
    {
        if(!types.isEmpty() && !(types.size() == 1 && getTypeName(types.iterator().next(), model).trim().equals("")))
        {
            writer.println("<a name=\"types\"><h2>Types</h2></a>");
            writer.println("<table class=\"types\">");
            writer.println("<thead>");
            writer.println("<tr><th class=\"type\">Type</th><th class=\"description\">Description</th></tr>");
            writer.println("</thead>");

            writer.println("<tbody>");
            for (Class<? extends ConfiguredObject> type : types)
            {
                writer.print("<tr><td class=\"type\">");
                writer.print(getTypeName(type, model));
                writer.print("</td><td class=\"description\">");
                writer.print(type.getAnnotation(ManagedObject.class).description());
                writer.println("</td></tr>");

            }
            writer.println("</tbody>");
        }

        writer.println("</table>");
    }

    private String getTypeName(final Class<? extends ConfiguredObject> type, Model model)
    {
        return type.getAnnotation(ManagedObject.class).type() == null
                            ? model.getTypeRegistry().getTypeClass(type).getSimpleName()
                            : type.getAnnotation(ManagedObject.class).type();
    }

    private void writeAttributes(final PrintWriter writer,
                                 final Class<? extends ConfiguredObject> configuredClass, final Model model,
                                 final List<Class<? extends ConfiguredObject>> types)
    {
        writer.println("<a name=\"types\"><h2>Attributes</h2></a>");
        writer.println("<h2>Common Attributes</h2>");

        writeAttributesTable(writer, model.getTypeRegistry().getAttributeTypes(configuredClass).values());

        for(Class<? extends ConfiguredObject> type : types)
        {
            String typeName = getTypeName(type, model);
            Collection<ConfiguredObjectAttribute<?, ?>> typeSpecificAttributes =
                    model.getTypeRegistry().getTypeSpecificAttributes(type);
            if(!typeSpecificAttributes.isEmpty())
            {
                writer.println("<h2><span class=\"type\">"+typeName+"</span> Specific Attributes</h2>");
                writeAttributesTable(writer, typeSpecificAttributes);
            }


        }

    }

    private void writeAttributesTable(final PrintWriter writer,
                                      final Collection<ConfiguredObjectAttribute<?, ?>> attributeTypes)
    {
        writer.println("<table class=\"attributes\">");
        writer.println("<thead>");
        writer.println("<tr><th class=\"name\">Attribute Name</th><th class=\"type\">Type</th><th class=\"properties\">Properties</th><th class=\"description\">Description</th></tr>");
        writer.println("</thead>");
        writer.println("<tbody>");

        for(ConfiguredObjectAttribute attribute : attributeTypes)
        {
            String properties;
            if (attribute instanceof ConfiguredSettableAttribute)
            {
                ConfiguredSettableAttribute settableAttribute = (ConfiguredSettableAttribute)attribute;
                if (settableAttribute.isImmutable())
                {
                    properties = "read/settable on create only";
                }
                else
                {
                    properties = "read/write";
                }
            }
            else
            {
                properties = "read only";
            }
            writer.println("<tr><td class=\"name\">"
                           + attribute.getName()
                           + "</td><td class=\"type\">"
                           + renderType(attribute)
                           + "</td><td class=\"properties\">"
                           + properties
                           + "</td><td class=\"description\">"
                           + attribute.getDescription()
                           + "</td></tr>");
        }
        writer.println("</tbody>");

        writer.println("</table>");

    }
    private void writeStatistics(final PrintWriter writer,
                                 final Class<? extends ConfiguredObject> configuredClass, final Model model,
                                 final List<Class<? extends ConfiguredObject>> types)
    {
        writer.println("<a name=\"types\"><h2>Statistics</h2></a>");
        writer.println("<h2>Common Statistics</h2>");

        writeStatisticsTable(writer, model.getTypeRegistry().getStatistics(configuredClass));

        for(Class<? extends ConfiguredObject> type : types)
        {
            String typeName = getTypeName(type, model);
            Collection<ConfiguredObjectStatistic<?, ?>> typeSpecificStatistics =
                    model.getTypeRegistry().getTypeSpecificStatistics(type);
            if(!typeSpecificStatistics.isEmpty())
            {
                writer.println("<h2><span class=\"type\">"+typeName+"</span> Specific Statistics</h2>");
                writeStatisticsTable(writer, typeSpecificStatistics);
            }
        }
    }

    private void writeStatisticsTable(final PrintWriter writer,
                                      final Collection<ConfiguredObjectStatistic<?,?>> statisticTypes)
    {
        writer.println("<table class=\"statistics\">");
        writer.println("<thead>");
        writer.println("<tr><th class=\"name\">Statistic Name</th><th class=\"type\">Type</th><th class=\"units\">Units</th><th class=\"statisticType\">Stat Type</th><th class=\"description\">Description</th></tr>");
        writer.println("</thead>");
        writer.println("<tbody>");

        for(ConfiguredObjectStatistic statistic : statisticTypes)
        {
            writer.println("<tr><td class=\"name\">"
                           + statistic.getName()
                           + "</td><td class=\"type\">"
                           + renderType(statistic)
                           + "</td><td class=\"units\">"
                           + statistic.getUnits()
                           + "</td><td class=\"stattype\">"
                           + statistic.getStatisticType()
                           + "</td><td class=\"description\">"
                           + statistic.getDescription()
                           + "</td></tr>");
        }
        writer.println("</tbody>");

        writer.println("</table>");

    }

    private void writeOperations(final PrintWriter writer,
                                 final Class<? extends ConfiguredObject> configuredClass, final Model model,
                                 final List<Class<? extends ConfiguredObject>> types)
    {
        writer.println("<a name=\"types\"><h2>Operations</h2></a>");
        writer.println("<h2>Common Operations</h2>");

        Collection<ConfiguredObjectOperation<?>> categoryOperations =
                model.getTypeRegistry().getOperations(configuredClass).values();
        writeOperationsTables(writer, categoryOperations);
        for(Class<? extends ConfiguredObject> type : types)
        {
            String typeName = getTypeName(type, model);
            Set<ConfiguredObjectOperation<?>> typeSpecificOperations = new HashSet<>(model.getTypeRegistry().getOperations(type).values());
            typeSpecificOperations.removeAll(categoryOperations);

            if(!typeSpecificOperations.isEmpty() && type != configuredClass)
            {
                writer.println("<h2><span class=\"type\">"+typeName+"</span> Specific Operations</h2>");
                writeOperationsTables(writer, typeSpecificOperations);
            }
        }

    }

    private void writeOperationsTables(PrintWriter writer,
                                       Collection<ConfiguredObjectOperation<?>> operations)
    {
        for(ConfiguredObjectOperation<?> operation : operations)
        {
            writer.println("<table class=\"operation\">");
            writer.println("<thead>");
            writer.println("<tr><th class=\"name\">Operation Name</th><th class=\"returnType\">Return Type</th><th class=\"description\">Description</th></tr>");
            writer.println("</thead>");
            writer.println("<tbody>");

            writer.println("<tr><td class=\"name\">"
                           + operation.getName()
                           + "</td><td class=\"type\">"
                           + renderType(operation)
                           + "</td><td class=\"description\">"
                           + operation.getDescription()
                           + "</td></tr>");
            if (!operation.getParameters().isEmpty())
            {
                writer.println("<tr><td class=\"allparameters\" colspan=\"3\">"
                               + renderParameters(operation.getParameters())
                               + "</td></tr>");
            }

            writer.println("</tbody>");
            writer.println("</table>");
        }
    }

    private String renderParameters(final List<OperationParameter> parameters)
    {
        StringBuilder writer = new StringBuilder();

        writer.append("<table class=\"parameters\">");
        writer.append("<thead>");
        writer.append(
                "<tr><th class=\"name\">Parameter Name</th><th>Type</th><th>Default</th><th>Mandatory?</th><th>Description</th></tr>");
        writer.append("</thead>");
        writer.append("<tbody>");

        for (OperationParameter param : parameters)
        {
            writer.append("<tr><td class=\"name\">"
                          + param.getName()
                          + "</td><td class=\"type\">"
                          + renderType(param)
                          + "</td><td class=\"default\">"
                          + param.getDefaultValue()
                          + "</td><td class=\"mandatory\">"
                          + param.isMandatory()
                          + "</td><td class=\"description\">"
                          + param.getDescription()
                          + "</td></tr>");
        }

        writer.append("</tbody>");
        writer.append("</table>");

        return writer.toString();
    }

    private String renderType(final ConfiguredObjectAttributeOrStatistic attributeOrStatistic)
    {
        final Class type = attributeOrStatistic.getType();

        Collection<String> validValues;
        String validValuePattern;

        if(attributeOrStatistic instanceof ConfiguredSettableAttribute)
        {
            ConfiguredSettableAttribute<?,?> settableAttribute = (ConfiguredSettableAttribute<?,?>) attributeOrStatistic;
            validValues = settableAttribute.hasValidValues() ? settableAttribute.validValues() : null;
            validValuePattern = settableAttribute.validValuePattern();
        }
        else
        {
            validValues = null;
            validValuePattern = "";
        }

        return renderType(type, validValues, validValuePattern);
    }

    private String renderType(final OperationParameter parameter)
    {
        final Class type = parameter.getType();
        List<String> validValues = parameter.getValidValues();
        return renderType(type, validValues, "");
    }

    private String renderType(Class type, Collection<String> validValues, final String validValuePattern) {
        if(Enum.class.isAssignableFrom(type))
        {
            return "<div class=\"restriction\" title=\"enum: " + EnumSet.allOf(type) + "\">string</div>";
        }
        else if(ConfiguredObject.class.isAssignableFrom(type))
        {
            return "<div class=\"restriction\" title=\"name or id of a" + (VOWELS.contains(type.getSimpleName().toLowerCase().charAt(0)) ? "n " : " ") + type.getSimpleName() + "\">string</div>";
        }
        else if(UUID.class == type)
        {
            return "<div class=\"restriction\" title=\"must be a UUID\">string</div>";
        }
        else
        {
            StringBuilder returnVal = new StringBuilder();
            final boolean hasValuesRestriction = validValues != null && !validValues.isEmpty();

            // TODO - valid values and patterns might contain characters which should be escaped
            if(hasValuesRestriction)
            {
                returnVal.append("<div class=\"restricted\" title=\"Valid values: " + validValues + "\">");
            }
            else if(validValuePattern != null && !"".equals(validValuePattern))
            {
                returnVal.append("<div class=\"restricted\" title=\"Valid value pattern: " + validValuePattern+ "\">");
            }

            if(Number.class.isAssignableFrom(type))
            {
                returnVal.append("number");
            }
            else if(Boolean.class == type)
            {
                returnVal.append("boolean");
            }
            else if(String.class == type)
            {
                returnVal.append("string");
            }
            else if(Collection.class.isAssignableFrom(type))
            {
                // TODO - generate a description of the type in the array
                returnVal.append("array");
            }
            else if(Map.class.isAssignableFrom(type))
            {
                // TODO - generate a description of the type in the object
                returnVal.append("object");
            }
            else
            {
                returnVal.append(type.getSimpleName());
            }
            if(hasValuesRestriction)
            {
                returnVal.append("</div>");
            }
            return returnVal.toString();
        }
    }

    private String renderType(final ConfiguredObjectOperation<?> operation)
    {
        return operation.getGenericReturnType() instanceof Class ?
                ((Class) operation.getGenericReturnType()).getName() :
                operation.getGenericReturnType().toString();
    }

    private void writeContext(final PrintWriter writer,
                              final Class<? extends ConfiguredObject> configuredClass,
                              final Model model, final List<Class<? extends ConfiguredObject>> types)
    {
        writer.println("<a name=\"types\"><h2>Context Variables</h2></a>");
        writer.println("<h2>Common Context Variables</h2>");

        Collection<ManagedContextDefault> defaultContexts =
                model.getTypeRegistry().getContextDependencies(configuredClass);
        writeContextDefaults(writer, defaultContexts);
        for(Class<? extends ConfiguredObject> type : types)
        {
            String typeName = getTypeName(type, model);
            Collection<ManagedContextDefault> typeSpecificDefaults = model.getTypeRegistry().getTypeSpecificContextDependencies(type);

            if(!typeSpecificDefaults.isEmpty() && type != configuredClass)
            {
                writer.println("<h2><span class=\"type\">"+typeName+"</span> Specific Context Variables</h2>");
                writeContextDefaults(writer, typeSpecificDefaults);
            }
        }

    }

    private void writeContextDefaults(PrintWriter writer,
                                       Collection<ManagedContextDefault> contextDefaults)
    {
        writer.println("<table class=\"contextDefault\">");
        writer.println("<thead>");
        writer.println("<tr><th class=\"name\">Name</th><th class=\"description\">Description</th></tr>");
        writer.println("</thead>");
        writer.println("<tbody>");

        for(ManagedContextDefault contextDefault : contextDefaults)
        {

            writer.println("<tr><td class=\"name\">"
                           + contextDefault.name()
                           + "</td><td class=\"description\">"
                           + contextDefault.description()
                           + "</td></tr>");
        }
        writer.println("</tbody>");
        writer.println("</table>");

    }


    private void writeFoot(final PrintWriter writer)
    {
        writer.println("</body>");
        writer.println("</html>");
    }

    private Class<? extends ConfiguredObject> getConfiguredClass(HttpServletRequest request, ConfiguredObject<?> managedObject)
    {
        final String[] servletPathElements = request.getServletPath().split("/");
        String categoryName = servletPathElements[servletPathElements.length-1];
        Model model = managedObject.getModel();
        for(Class<? extends ConfiguredObject> category : model.getSupportedCategories())
        {
            if(category.getSimpleName().toLowerCase().equals(categoryName))
            {
                return category;
            }
        }
        return null;
    }
}
