/*
 * 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 java.util.regex.Pattern;

import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;

import org.apache.felix.http.base.internal.handler.ServletHandler;
import org.apache.felix.http.base.internal.service.HttpServiceFactory;

/**
 * The path resolver factory creates a path resolver for a pattern.
 * The servlet spec supports different patterns
 * - path mapping, a pattern starting with / and ending with /*
 * - extension mapping, a pattern starting with *.
 * - default mapping, the pattern /
 * - root mapping, the pattern is the empty string
 * - exact match
 *
 * Exact match is tried first, followed by longest match and finally
 * extension match.
 */
public abstract class PathResolverFactory {

    public static @NotNull PathResolver createPatternMatcher(@Nullable final ServletHandler handler, @NotNull final String pattern)
    {
        if ( pattern.length() == 0 )
        {
            return new RootMatcher(handler);
        }
        else if ( pattern.equals("/") )
        {
            return new DefaultMatcher(handler);
        }
        else if ( pattern.startsWith("*.") )
        {
            return new ExtensionMatcher(handler, pattern);
        }
        else if ( pattern.endsWith("/*") )
        {
            return new PathMatcher(handler, pattern);
        }
        else if ( handler != null && handler.getContextServiceId() == HttpServiceFactory.HTTP_SERVICE_CONTEXT_SERVICE_ID )
        {
            return new ExactAndPathMatcher(handler, pattern);
        }
        return new ExactMatcher(handler, pattern);
    }

    public static @NotNull PathResolver createRegexMatcher(@NotNull final String regex)
    {
        return new RegexMatcher(regex);
    }

    public static abstract class AbstractMatcher implements PathResolver
    {
        private final int ranking;

        private final String pattern;

        private final ServletHandler handler;

        public AbstractMatcher(final ServletHandler handler, final String pattern, final int ranking)
        {
            this.handler = handler;
            this.ranking = ranking;
            this.pattern = pattern;
        }

        @Override
        public int compareTo(final PathResolver o)
        {
            int result = o.getRanking() - this.ranking;
            if ( result == 0 )
            {
                result = o.getOrdering() - this.getOrdering();
            }
            return result;
        }

        @Override
        public ServletHandler getServletHandler()
        {
            return this.handler;
        }

        @Override
        public int getRanking()
        {
            return this.ranking;
        }

        @Override
        public int getOrdering()
        {
            return 0;
        }

        @Override
        public String getPattern()
        {
            return this.pattern;
        }

        @Override
        public int hashCode()
        {
            return pattern.hashCode();
        }

        @Override
        public boolean equals(final Object obj) {
            if (this == obj)
            {
                return true;
            }
            if (obj == null || getClass() != obj.getClass())
            {
                return false;
            }
            final AbstractMatcher other = (AbstractMatcher) obj;
            return this.pattern.equals(other.pattern);
        }
    }

    public static final class RootMatcher extends AbstractMatcher
    {
        public RootMatcher(final ServletHandler handler)
        {
            super(handler, "", 2);
        }

        @Override
        public PathResolution resolve(final String uri) {
            if ( uri.length() == 0 || uri.equals("/") )
            {
                final PathResolution pr = new PathResolution();
                pr.pathInfo = "/";
                pr.servletPath = "";
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            return null;
        }
    }

    public static final class DefaultMatcher extends AbstractMatcher
    {
        public DefaultMatcher(final ServletHandler handler)
        {
            super(handler, "/", 1);
        }

        @Override
        public PathResolution resolve(final String uri) {
            final PathResolution pr = new PathResolution();
            pr.pathInfo = null;
            pr.servletPath = uri;
            pr.requestURI = uri;
            pr.handler = this.getServletHandler();

            return pr;
        }
    }

    public static final class ExactAndPathMatcher extends AbstractMatcher
    {
        private final String path;

        private final String prefix;

        public ExactAndPathMatcher(final ServletHandler handler, final String pattern)
        {
            super(handler, pattern, 5);
            this.path = pattern;
            this.prefix = pattern.concat("/");
        }

        @Override
        public PathResolution resolve(final String uri) {
            if ( uri.equals(this.path) )
            {
                final PathResolution pr = new PathResolution();
                pr.pathInfo = null;
                pr.servletPath = uri;
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            else if ( uri.startsWith(prefix) )
            {
                final PathResolution pr = new PathResolution();
                pr.servletPath = this.prefix.substring(0, this.prefix.length() - 1);
                pr.pathInfo = uri.substring(pr.servletPath.length());
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            return null;
        }

        @Override
        public int getOrdering()
        {
            return this.path.length();
        }
    }

    public static final class ExactMatcher extends AbstractMatcher
    {
        private final String path;

        public ExactMatcher(final ServletHandler handler, final String pattern)
        {
            super(handler, pattern, 5);
            this.path = pattern;
        }

        @Override
        public PathResolution resolve(final String uri) {
            if ( uri.equals(this.path) )
            {
                final PathResolution pr = new PathResolution();
                pr.servletPath = uri;
                pr.pathInfo = null;
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            return null;
        }

        @Override
        public int getOrdering()
        {
            return this.path.length();
        }
    }

    public static final class PathMatcher extends AbstractMatcher
    {
        private final String prefix;

        private final String path;

        public PathMatcher(final ServletHandler handler, final String pattern)
        {
            super(handler, pattern, 4);
            this.prefix = pattern.substring(0, pattern.length() - 1);
            this.path = pattern.substring(0, pattern.length() - 2);
        }

        @Override
        public PathResolution resolve(final String uri) {
            if ( uri.equals(this.path) )
            {
                final PathResolution pr = new PathResolution();
                pr.servletPath = this.path;
                pr.pathInfo = null;
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            if ( uri.startsWith(this.prefix) )
            {
                final PathResolution pr = new PathResolution();
                pr.servletPath = this.prefix.substring(0, this.prefix.length() - 1);
                pr.pathInfo = uri.substring(pr.servletPath.length());
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            return null;
        }

        @Override
        public int getOrdering()
        {
            return this.prefix.length() + 1;
        }
    }

    public static final class ExtensionMatcher extends AbstractMatcher
    {
        private final String extension;

        public ExtensionMatcher(final ServletHandler handler, final String pattern)
        {
            super(handler, pattern, 3);
            this.extension = pattern.substring(1);
        }

        @Override
        public PathResolution resolve(final String uri) {
            if ( uri.endsWith(this.extension) )
            {
                final PathResolution pr = new PathResolution();
                pr.pathInfo = null;
                pr.servletPath = uri;
                pr.requestURI = uri;
                pr.handler = this.getServletHandler();

                return pr;
            }
            return null;
        }

        @Override
        public int getOrdering()
        {
            return this.extension.length();
        }
    }

    public static final class RegexMatcher extends AbstractMatcher
    {
        private final Pattern pattern;

        public RegexMatcher(final String regex)
        {
            super(null, regex, 0);
            this.pattern = Pattern.compile(regex);
        }

        @Override
        public @Nullable PathResolution resolve(@NotNull final String uri) {
            if ( pattern.matcher(uri).matches() )
            {
                final PathResolution pr = new PathResolution();
                pr.pathInfo = null;
                pr.servletPath = uri;
                pr.requestURI = uri;

                return pr;
            }
            return null;
        }

        @Override
        public int getOrdering()
        {
            return this.pattern.toString().length();
        }
    }
}
