/*
 * 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.felix.http.base.internal.console;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.dto.ServiceReferenceDTO;
import org.osgi.service.http.runtime.HttpServiceRuntime;
import org.osgi.service.http.runtime.dto.DTOConstants;
import org.osgi.service.http.runtime.dto.ErrorPageDTO;
import org.osgi.service.http.runtime.dto.FailedErrorPageDTO;
import org.osgi.service.http.runtime.dto.FailedFilterDTO;
import org.osgi.service.http.runtime.dto.FailedListenerDTO;
import org.osgi.service.http.runtime.dto.FailedResourceDTO;
import org.osgi.service.http.runtime.dto.FailedServletContextDTO;
import org.osgi.service.http.runtime.dto.FailedServletDTO;
import org.osgi.service.http.runtime.dto.FilterDTO;
import org.osgi.service.http.runtime.dto.ListenerDTO;
import org.osgi.service.http.runtime.dto.RequestInfoDTO;
import org.osgi.service.http.runtime.dto.ResourceDTO;
import org.osgi.service.http.runtime.dto.RuntimeDTO;
import org.osgi.service.http.runtime.dto.ServletContextDTO;
import org.osgi.service.http.runtime.dto.ServletDTO;

/**
 * This is a web console plugin.
 */
@SuppressWarnings("serial")
public class HttpServicePlugin extends HttpServlet
{
    private static final String ATTR_TEST = "test";
    private static final String ATTR_MSG = "msg";
    private static final String ATTR_SUBMIT = "resolve";


    private final HttpServiceRuntime runtime;
    private final BundleContext context;

    private volatile ServiceRegistration<Servlet> serviceReg;

    public HttpServicePlugin(final BundleContext context, final HttpServiceRuntime runtime)
    {
        this.runtime = runtime;
        this.context = context;
    }

    public void register()
    {
        final Dictionary<String, Object> props = new Hashtable<>();
        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
        props.put(Constants.SERVICE_DESCRIPTION, "HTTP Service Web Console Plugin");
        props.put("felix.webconsole.label", "httpservice");
        props.put("felix.webconsole.title", "HTTP Service");
        props.put("felix.webconsole.configprinter.modes", "always");
        this.serviceReg = context.registerService(Servlet.class, this, props);
    }

    /** Escape xml text */
    private static String escapeXml(final String input) {
        if (input == null) {
            return null;
        }

        final StringBuilder b = new StringBuilder(input.length());
        for(int i = 0;i  < input.length(); i++) {
            final char c = input.charAt(i);
            if(c == '&') {
                b.append("&amp;");
            } else if(c == '<') {
                b.append("&lt;");
            } else if(c == '>') {
                b.append("&gt;");
            } else if(c == '"') {
                b.append("&quot;");
            } else if(c == '\'') {
                b.append("&apos;");
            } else {
                b.append(c);
            }
        }
        return b.toString();
    }

    @Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        final String test = request.getParameter(ATTR_TEST);
        String msg = null;
        if (test != null && test.length() > 0) {

            final RequestInfoDTO dto = this.runtime.calculateRequestInfoDTO(test);

            final StringBuilder sb = new StringBuilder();
            if ( dto.servletDTO != null )
            {
                sb.append("Servlet: ");
                sb.append(getValueAsString(dto.servletDTO.patterns));
                sb.append(" (");
                sb.append("service.id=");
                sb.append(String.valueOf(dto.servletDTO.serviceId));
                sb.append("), Filters: [");
                boolean first = true;
                for(final FilterDTO f : dto.filterDTOs)
                {
                    if ( first )
                    {
                        first = false;
                    }
                    else
                    {
                        sb.append(", ");
                    }
                    sb.append(f.serviceId);
                }
                sb.append("]");
            }
            else if ( dto.resourceDTO != null )
            {
                sb.append("Resource: ");
                sb.append(getValueAsString(dto.resourceDTO.patterns));
                sb.append(" (");
                sb.append("service.id=");
                sb.append(String.valueOf(dto.resourceDTO.serviceId));
                sb.append("), Filters: [");
                boolean first = true;
                for(final FilterDTO f : dto.filterDTOs)
                {
                    if ( first )
                    {
                        first = false;
                    }
                    else
                    {
                        sb.append(", ");
                    }
                    sb.append(f.serviceId);
                }
                sb.append("]");
            }
            else
            {
                sb.append("<404>");
            }
            msg = sb.toString();
        }

        // finally redirect
        final String path = request.getContextPath() + request.getServletPath()
                + request.getPathInfo();
        final String redirectTo;
        if (msg == null) {
            redirectTo = path;
        } else {
            redirectTo = path + '?' + ATTR_MSG + '=' + encodeParam(msg) + '&'
                    + ATTR_TEST + '=' + encodeParam(test);
        }
        response.sendRedirect(redirectTo);
    }

    private String encodeParam(final String value) {
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // should never happen
            return value;
        }
    }

    @Override
    protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException
    {
        final RuntimeDTO dto = this.runtime.getRuntimeDTO();

        final PrintWriter pw = resp.getWriter();

        String path = req.getContextPath() + req.getServletPath();
        if ( req.getPathInfo() != null ) {
            path = path + req.getPathInfo();
        }
        printForm(pw, req.getParameter(ATTR_TEST), req.getParameter(ATTR_MSG), path);

        printRuntimeDetails(pw, dto.serviceDTO);

        for(final ServletContextDTO ctxDto : dto.servletContextDTOs )
        {
            printContextDetails(pw, ctxDto);
        }
        for(final FailedServletContextDTO ctxDto : dto.failedServletContextDTOs )
        {
            printFailedContextDetails(pw, ctxDto);
        }
        printFailedServletDetails(pw, dto);
        printFailedFilterDetails(pw, dto);
        printFailedResourceDetails(pw, dto);
        printFailedErrorPageDetails(pw, dto);
        printFailedListenerDetails(pw, dto);

        pw.println("<br/>");
    }

    private void printForm(final PrintWriter pw, final String value, final String msg, final String path)
    {
        pw.println("<table class='content' cellpadding='0' cellspacing='0' width='100%'>");

        separatorHtml(pw);

        titleHtml(
                pw,
                "Test Servlet Resolution",
                "To test the servlet resolution, enter a relative URL into "
                        + "the field and click 'Resolve'.");

        pw.println("<tr class='content'>");
        pw.println("<td class='content'>Test</td>");
        pw.print("<td class='content' colspan='2'>");
        pw.print("<form method='POST' action='");
        pw.print(path);
        pw.print("'>");
        pw.print("<input type='text' name='" + ATTR_TEST + "' value='");
        if (value != null) {
            pw.print(escapeXml(value));
        }
        pw.println("' class='input' size='50'>");
        pw.println("&nbsp;&nbsp;<input type='submit' name='" + ATTR_SUBMIT
                + "' value='Resolve' class='submit'>");
        pw.print("</form>");
        pw.print("</td>");
        pw.println("</tr>");

        if (msg != null) {
            pw.println("<tr class='content'>");
            pw.println("<td class='content'>&nbsp;</td>");
            pw.print("<td class='content' colspan='2'>");
            pw.print(escapeXml(msg));
            pw.println("</td>");
            pw.println("</tr>");
        }
        pw.println("</table>");
    }

    private void titleHtml(PrintWriter pw, String title, String description)
    {
        pw.println("<tr class='content'>");
        pw.println("<th colspan='3'class='content container'>" + title
                + "</th>");
        pw.println("</tr>");

        if (description != null) {
            pw.println("<tr class='content'>");
            pw.println("<td colspan='3'class='content'>" + description
                    + "</th>");
            pw.println("</tr>");
        }
    }

    private void separatorHtml(PrintWriter pw)
    {
        pw.println("<tr class='content'>");
        pw.println("<td class='content' colspan='3'>&nbsp;</td>");
        pw.println("</tr>");
    }

    private String getValueAsString(final Object value)
    {
        if ( value.getClass().isArray() )
        {
            if (value instanceof long[])
            {
                return Arrays.toString((long[])value);
            }
            else if (value instanceof int[])
            {
                return Arrays.toString((int[])value);
            }
            else if (value instanceof double[])
            {
                return Arrays.toString((double[])value);
            }
            else if (value instanceof byte[])
            {
                return Arrays.toString((byte[])value);
            }
            else if (value instanceof float[])
            {
                return Arrays.toString((float[])value);
            }
            else if (value instanceof short[])
            {
                return Arrays.toString((short[])value);
            }
            else if (value instanceof boolean[])
            {
                return Arrays.toString((boolean[])value);
            }
            else if (value instanceof char[])
            {
                return Arrays.toString((char[])value);
            }
            else
            {
                return Arrays.toString((Object[])value);
            }
        }
        return value.toString();
    }

    private void printRuntimeDetails(final PrintWriter pw, final ServiceReferenceDTO dto)
    {
        pw.println("<p class=\"statline ui-state-highlight\">${Runtime Properties}</p>");
        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Value}</th>");
        pw.println("</tr></thead>");
        boolean odd = true;
        for(final Map.Entry<String, Object> prop : dto.properties.entrySet())
        {
            odd = printRow(pw, odd, prop.getKey(), getValueAsString(prop.getValue()));
        }
        pw.println("</table>");
        pw.println("<br/>");
    }

    private boolean printRow(final PrintWriter pw, final boolean odd, final String...columns)
    {
        pw.print("<tr class=\"");
        if ( odd ) pw.print("odd"); else pw.print("even");
        pw.println(" ui-state-default\">");

        for(final String val : columns)
        {
            pw.print("<td>");
            if ( val != null )
            {
                String text = escapeXml(val).replace("\n", "<br/>");
                int pos;
                while ( (pos = text.indexOf("${#link:")) != -1)
                {
                    final int endPos = text.indexOf("}", pos);
                    final int bundleId = Integer.valueOf(text.substring(pos + 8, endPos));
                    final int tokenEndPos = text.indexOf("${link#}", pos);

                    text = text.substring(0, pos) + "<a href=\"${appRoot}/bundles/" + String.valueOf(bundleId) + "\">" +
                           text.substring(endPos + 1, tokenEndPos) + "</a>" + text.substring(tokenEndPos + 8);
                }
                pw.print(text);
            }
            pw.println("</td>");
        }

        pw.println("</tr>");
        return !odd;
    }

    private String getContextPath(final String path)
    {
        if ( path.length() == 0 )
        {
            return "<root>";
        }
        return path;
    }

    private boolean printServiceRankingRow(final PrintWriter pw, final long serviceId, final boolean odd)
    {
        int ranking = 0;
        final ServiceReference<?> ref = this.getServiceReference(serviceId);
        if ( ref != null )
        {
            final Object obj = ref.getProperty(Constants.SERVICE_RANKING);
            if ( obj instanceof Integer)
            {
                ranking = (Integer)obj;
            }
        }
        return printRow(pw, odd, "${ranking}", String.valueOf(ranking));
    }

    private void printContextDetails(final PrintWriter pw, final ServletContextDTO dto)
    {
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("'</p>");

        pw.println("<table class=\"nicetable\">");

        boolean odd = true;
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Value)}</th>");
        pw.println("</tr></thead>");
        odd = printRow(pw, odd, "${Path}", getContextPath(dto.contextPath));
        odd = printRow(pw, odd, "${service.id}", String.valueOf(dto.serviceId));
        odd = printServiceRankingRow(pw, dto.serviceId, odd);
        pw.println("</table>");

        printServletDetails(pw, dto);
        printFilterDetails(pw, dto);
        printResourceDetails(pw, dto);
        printErrorPageDetails(pw, dto);
        printListenerDetails(pw, dto);

        pw.println("<br/>");
    }

    private void printFailedContextDetails(final PrintWriter pw, final FailedServletContextDTO dto)
    {
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("'</p>");

        pw.println("<table class=\"nicetable\">");

        boolean odd = true;
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Value)}</th>");
        pw.println("</tr></thead>");
        odd = printRow(pw, odd, "${Path}",
                dto.contextPath == null ? dto.contextPath : getContextPath(dto.contextPath));
        odd = printRow(pw, odd, "${reason}", escapeXml(getErrorText(dto.failureReason)));
        odd = printRow(pw, odd, "${service.id}", String.valueOf(dto.serviceId));
        pw.println("</table>");
    }

    private void appendServiceRanking(final StringBuilder sb, final ServiceReference<?> ref)
    {
        int ranking = 0;
        if ( ref != null )
        {
            final Object obj = ref.getProperty(Constants.SERVICE_RANKING);
            if ( obj instanceof Integer)
            {
                ranking = (Integer)obj;
            }
        }
        sb.append("${ranking} : ").append(String.valueOf(ranking)).append("\n");
    }

    private void printFilterDetails(final PrintWriter pw, final ServletContextDTO dto)
    {
        if ( dto.filterDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("' ${Registered Filter Services}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Pattern}</th>");
        pw.println("<th class=\"header\">${Filter}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final FilterDTO filter : dto.filterDTOs)
        {
            final ServiceReference<?> ref = this.getServiceReference(filter.serviceId);
            final StringBuilder sb = new StringBuilder();
            sb.append("${service.id} : ").append(String.valueOf(filter.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            sb.append("${async} : ").append(String.valueOf(filter.asyncSupported)).append("\n");
            sb.append("${dispatcher} : ").append(getValueAsString(filter.dispatcher)).append("\n");
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final List<String> patterns = new ArrayList<>();
            patterns.addAll(Arrays.asList(filter.patterns));
            patterns.addAll(Arrays.asList(filter.regexs));
            for(final String name : filter.servletNames)
            {
                patterns.add("Servlet : " + name);
            }
            Collections.sort(patterns);
            final StringBuilder psb = new StringBuilder();
            for(final String p : patterns)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), filter.name, sb.toString());
        }
        pw.println("</table>");
    }

    private String getErrorText(final int reason)
    {
        switch ( reason )
        {
        case DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT : return "Exception on init";
        case DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING : return "No match";
        case DTOConstants.FAILURE_REASON_SERVICE_IN_USE : return "In use";
        case DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE : return "Not gettable";
        case DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE : return "Context failure";
        case DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE : return "Shadowed";
        case DTOConstants.FAILURE_REASON_VALIDATION_FAILED : return "Invalid";
        default: return "unknown";
        }
    }
    private void printFailedFilterDetails(final PrintWriter pw, final RuntimeDTO dto)
    {
        if ( dto.failedFilterDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Failed Filter Services}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Pattern}</th>");
        pw.println("<th class=\"header\">${Filter}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final FailedFilterDTO filter : dto.failedFilterDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            sb.append("${reason} : ").append(getErrorText(filter.failureReason)).append("\n");
            final ServiceReference<?> ref = this.getServiceReference(filter.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(filter.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            sb.append("${async} : ").append(String.valueOf(filter.asyncSupported)).append("\n");
            sb.append("${dispatcher} : ").append(getValueAsString(filter.dispatcher)).append("\n");
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final List<String> patterns = new ArrayList<>();
            patterns.addAll(Arrays.asList(filter.patterns));
            patterns.addAll(Arrays.asList(filter.regexs));
            for(final String name : filter.servletNames)
            {
                patterns.add("Servlet : " + name);
            }
            Collections.sort(patterns);
            final StringBuilder psb = new StringBuilder();
            for(final String p : patterns)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), filter.name, sb.toString());
        }
        pw.println("</table>");
    }

    private ServiceReference<?> getServiceReference(final long serviceId)
    {
        if ( serviceId > 0 )
        {
            try
            {
                final ServiceReference<?>[] ref = this.context.getServiceReferences((String)null, "(" + Constants.SERVICE_ID + "=" + String.valueOf(serviceId) + ")");
                if ( ref != null && ref.length > 0 )
                {
                    return ref[0];
                }
            }
            catch (final InvalidSyntaxException e)
            {
                // ignore
            }
        }
        return null;
    }

    private void printServletDetails(final PrintWriter pw, final ServletContextDTO dto)
    {
        if ( dto.servletDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("' ${Registered Servlet Services}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Path}</th>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final ServletDTO servlet : dto.servletDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            final ServiceReference<?> ref = this.getServiceReference(servlet.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(servlet.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            sb.append("${async} : ").append(String.valueOf(servlet.asyncSupported)).append("\n");
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final StringBuilder psb = new StringBuilder();
            for(final String p : servlet.patterns)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), servlet.name, sb.toString());
        }
        pw.println("</table>");
    }

    private void printFailedServletDetails(final PrintWriter pw, final RuntimeDTO dto)
    {
        if ( dto.failedServletDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Failed Servlet Services}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Path}</th>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final FailedServletDTO servlet : dto.failedServletDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            sb.append("${reason} : ").append(getErrorText(servlet.failureReason)).append("\n");
            final ServiceReference<?> ref = this.getServiceReference(servlet.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(servlet.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            sb.append("${async} : ").append(String.valueOf(servlet.asyncSupported)).append("\n");
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final StringBuilder psb = new StringBuilder();
            for(final String p : servlet.patterns)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), servlet.name, sb.toString());
        }
        pw.println("</table>");
    }

    private void printResourceDetails(final PrintWriter pw, final ServletContextDTO dto)
    {
        if ( dto.resourceDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("' ${Registered Resource Services}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Path}</th>");
        pw.println("<th class=\"header\">${Prefix}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final ResourceDTO rsrc : dto.resourceDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            final ServiceReference<?> ref = this.getServiceReference(rsrc.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(rsrc.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final StringBuilder psb = new StringBuilder();
            for(final String p : rsrc.patterns)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), rsrc.prefix, sb.toString());
        }
        pw.println("</table>");
    }

    private void printFailedResourceDetails(final PrintWriter pw, final RuntimeDTO dto)
    {
        if ( dto.failedResourceDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Failed Resource Services}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Path}</th>");
        pw.println("<th class=\"header\">${Prefix}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final FailedResourceDTO rsrc : dto.failedResourceDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            sb.append("${reason} : ").append(getErrorText(rsrc.failureReason)).append("\n");
            final ServiceReference<?> ref = this.getServiceReference(rsrc.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(rsrc.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final StringBuilder psb = new StringBuilder();
            for(final String p : rsrc.patterns)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), rsrc.prefix, sb.toString());
        }
        pw.println("</table>");
    }

    private void printErrorPageDetails(final PrintWriter pw, final ServletContextDTO dto)
    {
        if ( dto.errorPageDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("' ${Registered Error Pages}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Path}</th>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final ErrorPageDTO ep : dto.errorPageDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(ep.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            sb.append("${async} : ").append(String.valueOf(ep.asyncSupported)).append("\n");
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final StringBuilder psb = new StringBuilder();
            for(final long p : ep.errorCodes)
            {
                psb.append(p).append('\n');
            }
            for(final String p : ep.exceptions)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), ep.name, sb.toString());
        }
        pw.println("</table>");
    }

    private void printFailedErrorPageDetails(final PrintWriter pw, final RuntimeDTO dto)
    {
        if ( dto.failedErrorPageDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Registered Error Pages}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Path}</th>");
        pw.println("<th class=\"header\">${Name}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final FailedErrorPageDTO ep : dto.failedErrorPageDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            sb.append("${reason} : ").append(getErrorText(ep.failureReason)).append("\n");
            final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(ep.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            sb.append("${async} : ").append(String.valueOf(ep.asyncSupported)).append("\n");
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }

            final StringBuilder psb = new StringBuilder();
            for(final long p : ep.errorCodes)
            {
                psb.append(p).append('\n');
            }
            for(final String p : ep.exceptions)
            {
                psb.append(p).append('\n');
            }
            odd = printRow(pw, odd, psb.toString(), ep.name, sb.toString());
        }
        pw.println("</table>");
    }

    private void printListenerDetails(final PrintWriter pw, final ServletContextDTO dto)
    {
        if ( dto.listenerDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Servlet Context} '");
        pw.print(escapeXml(dto.name));
        pw.println("' ${Registered Listeners}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Type}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final ListenerDTO ep : dto.listenerDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(ep.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }
            final StringBuilder tsb = new StringBuilder();
            for(final String t : ep.types)
            {
                tsb.append(t).append('\n');
            }
            odd = printRow(pw, odd, tsb.toString(), sb.toString());
        }
        pw.println("</table>");
    }

    private void printFailedListenerDetails(final PrintWriter pw, final RuntimeDTO dto)
    {
        if ( dto.failedListenerDTOs.length == 0 )
        {
            return;
        }
        pw.print("<p class=\"statline ui-state-highlight\">${Failed Listeners}</p>");

        pw.println("<table class=\"nicetable\">");
        pw.println("<thead><tr>");
        pw.println("<th class=\"header\">${Type}</th>");
        pw.println("<th class=\"header\">${Info}</th>");
        pw.println("</tr></thead>");

        boolean odd = true;
        for (final FailedListenerDTO ep : dto.failedListenerDTOs)
        {
            final StringBuilder sb = new StringBuilder();
            sb.append("${reason} : ").append(getErrorText(ep.failureReason)).append("\n");
            final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
            sb.append("${service.id} : ").append(String.valueOf(ep.serviceId)).append("\n");
            appendServiceRanking(sb, ref);
            if ( ref != null )
            {
                sb.append("${bundle} : ");
                sb.append("${#link:");
                sb.append(ref.getBundle().getBundleId());
                sb.append("}");
                sb.append(ref.getBundle().getSymbolicName());
                sb.append("${link#}\n");
            }
            final StringBuilder tsb = new StringBuilder();
            for(final String t : ep.types)
            {
                tsb.append(t).append('\n');
            }
            odd = printRow(pw, odd, tsb.toString(), sb.toString());
        }
        pw.println("</table>");
    }

    private void printServiceIdAndRanking(final PrintWriter pw, final ServiceReference<?> ref, final long serviceId)
    {
        pw.print("service.id : ");
        pw.println(String.valueOf(serviceId));
        int ranking = 0;
        if ( ref != null )
        {
            final Object obj = ref.getProperty(Constants.SERVICE_RANKING);
            if ( obj instanceof Integer)
            {
                ranking = (Integer)obj;
            }
        }
        pw.print("Ranking : ");
        pw.println(String.valueOf(ranking));
    }

    /**
     * @see org.apache.felix.webconsole.ConfigurationPrinter#printConfiguration(java.io.PrintWriter)
     */
    public void printConfiguration(final PrintWriter pw)
    {
        final RuntimeDTO dto = this.runtime.getRuntimeDTO();

        pw.println("HTTP Service Details");
        pw.println("====================");
        pw.println();
        pw.println("Runtime Properties");
        pw.println("------------------");

        for(final Map.Entry<String, Object> prop : dto.serviceDTO.properties.entrySet())
        {
            pw.print(prop.getKey());
            pw.print(" : ");
            pw.println(getValueAsString(prop.getValue()));
        }
        pw.println();
        for(final ServletContextDTO ctxDto : dto.servletContextDTOs )
        {
            pw.print("Servlet Context ");
            pw.println(ctxDto.name);
            pw.println("-----------------------------------------------");

            pw.print("Path : ");
            pw.println(getContextPath(ctxDto.contextPath));
            printServiceIdAndRanking(pw, this.getServiceReference(ctxDto.serviceId), ctxDto.serviceId);
            pw.println();
            if ( ctxDto.servletDTOs.length > 0 )
            {
                pw.println("Servlets");
                for (final ServletDTO servlet : ctxDto.servletDTOs)
                {
                    pw.print("Patterns : ");
                    pw.println(getValueAsString(servlet.patterns));
                    pw.print("Name : ");
                    pw.println(servlet.name);
                    final ServiceReference<?> ref = this.getServiceReference(servlet.serviceId);
                    printServiceIdAndRanking(pw, ref, servlet.serviceId);
                    pw.print("async : ");
                    pw.println(String.valueOf(servlet.asyncSupported));
                    if ( ref != null )
                    {
                        pw.print("Bundle : ");
                        pw.print(ref.getBundle().getSymbolicName());
                        pw.print(" <");
                        pw.print(String.valueOf(ref.getBundle().getBundleId()));
                        pw.println(">");
                    }
                    pw.println();
                }
                pw.println();
            }

            if ( ctxDto.filterDTOs.length > 0 )
            {
                pw.println("Filters");
                for (final FilterDTO filter : ctxDto.filterDTOs)
                {
                    final List<String> patterns = new ArrayList<>();
                    patterns.addAll(Arrays.asList(filter.patterns));
                    patterns.addAll(Arrays.asList(filter.regexs));
                    for(final String name : filter.servletNames)
                    {
                        patterns.add("Servlet : " + name);
                    }
                    Collections.sort(patterns);

                    pw.print("Patterns : ");
                    pw.println(patterns);
                    pw.print("Name : ");
                    pw.println(filter.name);
                    final ServiceReference<?> ref = this.getServiceReference(filter.serviceId);
                    printServiceIdAndRanking(pw, ref, filter.serviceId);
                    pw.print("async : ");
                    pw.println(String.valueOf(filter.asyncSupported));
                    pw.print("dispatcher : ");
                    pw.println(getValueAsString(filter.dispatcher));
                    if ( ref != null )
                    {
                        pw.print("Bundle : ");
                        pw.print(ref.getBundle().getSymbolicName());
                        pw.print(" <");
                        pw.print(String.valueOf(ref.getBundle().getBundleId()));
                        pw.println(">");
                    }
                    pw.println();
                }
                pw.println();
            }
            if ( ctxDto.resourceDTOs.length > 0 )
            {
                pw.println("Resources");
                for (final ResourceDTO rsrc : ctxDto.resourceDTOs)
                {
                    pw.print("Patterns : ");
                    pw.println(getValueAsString(rsrc.patterns));
                    pw.print("Prefix : ");
                    pw.println(rsrc.prefix);
                    final ServiceReference<?> ref = this.getServiceReference(rsrc.serviceId);
                    printServiceIdAndRanking(pw, ref, rsrc.serviceId);
                    if ( ref != null )
                    {
                        pw.print("Bundle : ");
                        pw.print(ref.getBundle().getSymbolicName());
                        pw.print(" <");
                        pw.print(String.valueOf(ref.getBundle().getBundleId()));
                        pw.println(">");
                    }
                    pw.println();
                }
                pw.println();

            }
            if ( ctxDto.errorPageDTOs.length > 0 )
            {
                pw.println("Error Pages");
                for (final ErrorPageDTO ep : ctxDto.errorPageDTOs)
                {
                    final List<String> patterns = new ArrayList<>();
                    for(final long p : ep.errorCodes)
                    {
                        patterns.add(String.valueOf(p));
                    }
                    for(final String p : ep.exceptions)
                    {
                        patterns.add(p);
                    }
                    pw.print("Patterns : ");
                    pw.println(patterns);
                    pw.print("Name : ");
                    pw.println(ep.name);
                    final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
                    printServiceIdAndRanking(pw, ref, ep.serviceId);
                    pw.print("async : ");
                    pw.println(String.valueOf(ep.asyncSupported));
                    if ( ref != null )
                    {
                        pw.print("Bundle : ");
                        pw.print(ref.getBundle().getSymbolicName());
                        pw.print(" <");
                        pw.print(String.valueOf(ref.getBundle().getBundleId()));
                        pw.println(">");
                    }
                    pw.println();
                }
                pw.println();
            }

            if ( ctxDto.listenerDTOs.length > 0 )
            {
                pw.println("Listeners");
                for (final ListenerDTO ep : ctxDto.listenerDTOs)
                {
                    pw.print("Types : ");
                    pw.println(getValueAsString(ep.types));
                    final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
                    printServiceIdAndRanking(pw, ref, ep.serviceId);
                    if ( ref != null )
                    {
                        pw.print("Bundle : ");
                        pw.print(ref.getBundle().getSymbolicName());
                        pw.print(" <");
                        pw.print(String.valueOf(ref.getBundle().getBundleId()));
                        pw.println(">");
                    }
                    pw.println();
                }
                pw.println();
            }
            pw.println();
        }

        if ( dto.failedServletContextDTOs.length > 0 )
        {
            for(final FailedServletContextDTO ctxDto : dto.failedServletContextDTOs )
            {
                pw.print("Failed Servlet Context ");
                pw.println(ctxDto.name);
                pw.println("-----------------------------------------------");

                pw.print("Reason : ");
                pw.println(getErrorText(ctxDto.failureReason));
                pw.print("Path : ");
                pw.println(getContextPath(ctxDto.contextPath));
                printServiceIdAndRanking(pw, this.getServiceReference(ctxDto.serviceId), ctxDto.serviceId);
                pw.println();
            }
        }
        if ( dto.failedServletDTOs.length > 0 )
        {
            pw.println("Failed Servlets");
            for (final FailedServletDTO servlet : dto.failedServletDTOs)
            {
                pw.print("Patterns : ");
                pw.println(getValueAsString(servlet.patterns));
                pw.print("Reason : ");
                pw.println(getErrorText(servlet.failureReason));
                pw.print("Name : ");
                pw.println(servlet.name);
                final ServiceReference<?> ref = this.getServiceReference(servlet.serviceId);
                printServiceIdAndRanking(pw, ref, servlet.serviceId);
                pw.print("async : ");
                pw.println(String.valueOf(servlet.asyncSupported));
                if ( ref != null )
                {
                    pw.print("Bundle : ");
                    pw.print(ref.getBundle().getSymbolicName());
                    pw.print(" <");
                    pw.print(String.valueOf(ref.getBundle().getBundleId()));
                    pw.println(">");
                }
                pw.println();
            }
            pw.println();
        }

        if ( dto.failedFilterDTOs.length > 0 )
        {
            pw.println("Failed Filters");
            for (final FailedFilterDTO filter : dto.failedFilterDTOs)
            {
                final List<String> patterns = new ArrayList<>();
                patterns.addAll(Arrays.asList(filter.patterns));
                patterns.addAll(Arrays.asList(filter.regexs));
                for(final String name : filter.servletNames)
                {
                    patterns.add("Servlet : " + name);
                }
                Collections.sort(patterns);

                pw.print("Patterns : ");
                pw.println(patterns);
                pw.print("Reason : ");
                pw.println(getErrorText(filter.failureReason));
                pw.print("Name : ");
                pw.println(filter.name);
                final ServiceReference<?> ref = this.getServiceReference(filter.serviceId);
                printServiceIdAndRanking(pw, ref, filter.serviceId);
                pw.print("async : ");
                pw.println(String.valueOf(filter.asyncSupported));
                pw.print("dispatcher : ");
                pw.println(getValueAsString(filter.dispatcher));
                if ( ref != null )
                {
                    pw.print("Bundle : ");
                    pw.print(ref.getBundle().getSymbolicName());
                    pw.print(" <");
                    pw.print(String.valueOf(ref.getBundle().getBundleId()));
                    pw.println(">");
                }
                pw.println();
            }
            pw.println();
        }
        if ( dto.failedResourceDTOs.length > 0 )
        {
            pw.println("Failed Resources");
            for (final FailedResourceDTO rsrc : dto.failedResourceDTOs)
            {
                pw.print("Patterns : ");
                pw.println(getValueAsString(rsrc.patterns));
                pw.print("Reason : ");
                pw.println(getErrorText(rsrc.failureReason));
                pw.print("Prefix : ");
                pw.println(rsrc.prefix);
                final ServiceReference<?> ref = this.getServiceReference(rsrc.serviceId);
                printServiceIdAndRanking(pw, ref, rsrc.serviceId);
                if ( ref != null )
                {
                    pw.print("Bundle : ");
                    pw.print(ref.getBundle().getSymbolicName());
                    pw.print(" <");
                    pw.print(String.valueOf(ref.getBundle().getBundleId()));
                    pw.println(">");
                }
                pw.println();
            }
            pw.println();

        }
        if ( dto.failedErrorPageDTOs.length > 0 )
        {
            pw.println("Failed Error Pages");
            for (final FailedErrorPageDTO ep : dto.failedErrorPageDTOs)
            {
                final List<String> patterns = new ArrayList<>();
                for(final long p : ep.errorCodes)
                {
                    patterns.add(String.valueOf(p));
                }
                for(final String p : ep.exceptions)
                {
                    patterns.add(p);
                }
                pw.print("Patterns : ");
                pw.println(patterns);
                pw.print("Reason : ");
                pw.println(getErrorText(ep.failureReason));
                pw.print("Name : ");
                pw.println(ep.name);
                final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
                printServiceIdAndRanking(pw, ref, ep.serviceId);
                pw.print("async : ");
                pw.println(String.valueOf(ep.asyncSupported));
                if ( ref != null )
                {
                    pw.print("Bundle : ");
                    pw.print(ref.getBundle().getSymbolicName());
                    pw.print(" <");
                    pw.print(String.valueOf(ref.getBundle().getBundleId()));
                    pw.println(">");
                }
                pw.println();
            }
            pw.println();
        }

        if ( dto.failedListenerDTOs.length > 0 )
        {
            pw.println("Listeners");
            for (final FailedListenerDTO ep : dto.failedListenerDTOs)
            {
                pw.print("Types : ");
                pw.println(getValueAsString(ep.types));
                pw.print("Reason : ");
                pw.println(getErrorText(ep.failureReason));
                final ServiceReference<?> ref = this.getServiceReference(ep.serviceId);
                printServiceIdAndRanking(pw, ref, ep.serviceId);
                if ( ref != null )
                {
                    pw.print("Bundle : ");
                    pw.print(ref.getBundle().getSymbolicName());
                    pw.print(" <");
                    pw.print(String.valueOf(ref.getBundle().getBundleId()));
                    pw.println(">");
                }
                pw.println();
            }
            pw.println();
        }
        pw.println();
    }

    public void unregister()
    {
        if (this.serviceReg != null)
        {
            this.serviceReg.unregister();
            this.serviceReg = null;
        }
    }
}
