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

import javax.servlet.DispatcherType;

import org.apache.felix.http.base.internal.HttpConfig;
import org.apache.felix.http.base.internal.handler.FilterHandler;
import org.apache.felix.http.base.internal.handler.ListenerHandler;
import org.apache.felix.http.base.internal.handler.ServletHandler;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.ListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
import org.apache.felix.http.base.internal.runtime.dto.FailedDTOHolder;
import org.apache.felix.http.base.internal.service.HttpServiceFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.service.http.runtime.dto.ServletContextDTO;

/**
 * This registry keeps track of all processing components per context:
 * - servlets
 * - filters
 * - error pages
 */
public final class PerContextHandlerRegistry implements Comparable<PerContextHandlerRegistry>
{
    /** Service id of the context. */
    private final long serviceId;

    /** Ranking of the context. */
    private final int ranking;

    /** The context path. */
    private final String path;

    /** The context prefix. */
    private final String prefix;

    private final ServletRegistry servletRegistry = new ServletRegistry();

    private final FilterRegistry filterRegistry = new FilterRegistry();

    private final ErrorPageRegistry errorPageRegistry = new ErrorPageRegistry();

    private final EventListenerRegistry eventListenerRegistry = new EventListenerRegistry();

    private final HttpConfig config;


    /**
     * Default http service registry
     */
    public PerContextHandlerRegistry(@NotNull final HttpConfig config)
    {
        this.config = config;
        this.serviceId = HttpServiceFactory.HTTP_SERVICE_CONTEXT_SERVICE_ID;
        this.ranking = Integer.MAX_VALUE;
        this.path = "/";
        this.prefix = null;
    }

    /**
     * Registry for a servlet context helper (whiteboard support)
     * @param info The servlet context helper info
     */
    public PerContextHandlerRegistry(@NotNull final ServletContextHelperInfo info, @NotNull final HttpConfig config)
    {
        this.config = config;
        this.serviceId = info.getServiceId();
        this.ranking = info.getRanking();
        this.path = info.getPath();
        if ( this.path.equals("/") )
        {
            this.prefix = null;
        }
        else
        {
            this.prefix = this.path + "/";
        }
    }

    public long getContextServiceId()
    {
        return this.serviceId;
    }

    public HttpConfig getConfig()
    {
        return this.config;
    }

    public void removeAll()
    {
        this.errorPageRegistry.cleanup();
        this.eventListenerRegistry.cleanup();
        this.filterRegistry.cleanup();
        this.servletRegistry.cleanup();
    }

    @Override
    public int compareTo(@NotNull final PerContextHandlerRegistry other)
    {
        final int result = new Integer(other.path.length()).compareTo(this.path.length());
        if ( result == 0 ) {
            if (this.ranking == other.ranking)
            {
                // Service id's can be negative. Negative id's follow the reverse natural ordering of integers.
                int reverseOrder = ( this.serviceId <= 0 && other.serviceId <= 0 ) ? -1 : 1;
                return reverseOrder * new Long(this.serviceId).compareTo(other.serviceId);
            }

            return new Integer(other.ranking).compareTo(this.ranking);
        }
        return result;
    }

    public String isMatching(@NotNull final String requestURI)
    {
        if (requestURI.equals(this.path))
        {
            return "";
        }
        if (this.prefix == null)
        {
            return requestURI;
        }
        if (requestURI.startsWith(this.prefix))
        {
            return requestURI.substring(this.prefix.length() - 1);
        }
        return null;
    }

    public PathResolution resolve(@NotNull final String relativeRequestURI)
    {
        return this.servletRegistry.resolve(relativeRequestURI);
    }

    public ServletHandler resolveServletByName(final String name)
    {
        return this.servletRegistry.resolveByName(name);
    }

    /**
     * Get filter handlers for the request uri
     * @param servletHandler The servlet handler (might be null)
     * @param dispatcherType The dispatcher type
     * @param requestURI The request uri
     * @return The array of filter handlers, the array might be empty.
     */
    public @NotNull FilterHandler[] getFilterHandlers(@Nullable final ServletHandler servletHandler,
            @NotNull final DispatcherType dispatcherType,
            @NotNull final String requestURI)
    {
        return this.filterRegistry.getFilterHandlers(servletHandler, dispatcherType, requestURI);
    }

    /**
     * Get the servlet handling the error.
     * @param code The error code
     * @param exception The optional exception
     * @return The servlet handler or {@code null}.
     */
    public @Nullable ServletHandler getErrorHandler(final int code, @Nullable final Throwable exception)
    {
        return this.errorPageRegistry.get(exception, code);
    }

    public EventListenerRegistry getEventListenerRegistry()
    {
        return this.eventListenerRegistry;
    }

    /**
     * Create all DTOs for servlets, filters, resources and error pages
     * @param dto The servlet context DTO
     * @param failedDTOHolder The container for all failed DTOs
     */
    public void getRuntime(final ServletContextDTO dto,
            final FailedDTOHolder failedDTOHolder)
    {
        // collect filters
        this.filterRegistry.getRuntimeInfo(dto, failedDTOHolder.failedFilterDTOs);

        // collect error pages
        this.errorPageRegistry.getRuntimeInfo(dto, failedDTOHolder.failedErrorPageDTOs);

        // collect servlets and resources
        this.servletRegistry.getRuntimeInfo(dto, failedDTOHolder.failedServletDTOs, failedDTOHolder.failedResourceDTOs);

        // collect listeners
        this.eventListenerRegistry.getRuntimeInfo(dto, failedDTOHolder.failedListenerDTOs);
    }

    /**
     * Add a servlet
     * @param handler The servlet handler
     */
    public void registerServlet(@NotNull final ServletHandler handler)
    {
        this.servletRegistry.addServlet(handler);
        this.errorPageRegistry.addServlet(handler);
    }

    /**
     * Remove a servlet
     * @param servletInfo The servlet info
     * @param destroy Destroy the servlet
     */
    public void unregisterServlet(@NotNull final ServletInfo servletInfo, final boolean destroy)
    {
        this.servletRegistry.removeServlet(servletInfo, destroy);
        this.errorPageRegistry.removeServlet(servletInfo, destroy);
    }

    /**
     * Add a filter
     * @param handler The filter handler
     */
    public void registerFilter(@NotNull final FilterHandler handler)
    {
        this.filterRegistry.addFilter(handler);
    }

    /**
     * Remove a filter
     * @param info The filter info
     * @param destroy Destroy the filter
     */
    public void unregisterFilter(@NotNull final FilterInfo info, final boolean destroy)
    {
        this.filterRegistry.removeFilter(info, destroy);
    }

    /**
     * Register listeners
     * @param listenerHandler
     */
    public void registerListeners(@NotNull final ListenerHandler listenerHandler)
    {
        this.eventListenerRegistry.addListeners(listenerHandler);
    }

    /**
     * Unregister listeners
     *
     * @param info The listener info
     */
    public void unregisterListeners(@NotNull final ListenerInfo info)
    {
        this.eventListenerRegistry.removeListeners(info);
    }

}
