/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package org.apache.sling.api.wrappers;

import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceWrapper;
import org.apache.sling.api.resource.mapping.PathRewriter;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ConsumerType;

/**
 * The {@code ResourceResolverWrapper} is a wrapper for any {@code ResourceResolver}, delegating all method calls to the wrapped resource
 * resolver by default. Extensions of this class may overwrite any method to return different values as appropriate.
 */
@ConsumerType
public class ResourceResolverWrapper implements ResourceResolver {

    private ResourceResolver wrapped;

    /**
     * Creates a new wrapper instance, delegating all calls to the given {@code resolver}.
     *
     * @param resolver the wrapped resource resolver
     */
    public ResourceResolverWrapper(ResourceResolver resolver) {
        wrapped = resolver;
    }

    /**
     * Wraps and returns the {@code Resource} obtained by calling {@code resolve} on the wrapped resource resolver.
     *
     * @param request The http servlet request object providing more hints at
     *                how to resolve the <code>absPath</code>. This parameter may be
     *                <code>null</code> in which case the implementation should use
     *                reasonable defaults.
     * @param absPath The absolute path to be resolved to a resource. If this
     *                parameter is <code>null</code>, it is assumed to address the
     *                root of the resource tree. If the path is relative it is
     *                assumed relative to the root, that is a slash is prepended to
     *                the path before resolving it.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @NotNull
    @Override
    public Resource resolve(@NotNull HttpServletRequest request, @NotNull String absPath) {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.resolve(request, absPath));
    }

    /**
     * Wraps and returns the {@code Resource} obtained by calling {@code resolve} on the wrapped resource resolver.
     *
     * @param absPath The absolute path to be resolved to a resource. If this
     *                parameter is <code>null</code>, it is assumed to address the
     *                root of the resource tree. If the path is relative it is
     *                assumed relative to the root, that is a slash is prepended to
     *                the path before resolving it.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @NotNull
    @Override
    public Resource resolve(@NotNull String absPath) {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.resolve(absPath));
    }

    /**
     * Wraps and returns the {@code Resource} obtained by calling {@code resolve} on the wrapped resource resolver.
     *
     * @param request The http servlet request object used to resolve the
     *                resource for. This must not be <code>null</code>.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @SuppressWarnings("deprecation")
    @NotNull
    @Override
    public Resource resolve(@NotNull HttpServletRequest request) {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.resolve(request));
    }

    @NotNull
    @Override
    public String map(@NotNull String resourcePath) {
        return wrapped.map(resourcePath);
    }

    @Override
    public String map(@NotNull HttpServletRequest request, @NotNull String resourcePath) {
        return wrapped.map(request, resourcePath);
    }

    @Override
    public @NotNull Resource resolveResource(@NotNull String path) {
        return wrapped.resolveResource(path);
    }

    @Override
    public @NotNull PathRewriter getPathRewriter() {
        return wrapped.getPathRewriter();
    }

    /**
     * Wraps and returns the {@code Resource} obtained by calling {@code getResource} on the wrapped resource resolver.
     *
     * @param path The absolute path to the resource object to be loaded. The
     *             path may contain relative path specifiers like <code>.</code>
     *             (current location) and <code>..</code> (parent location),
     *             which are resolved by this method. If the path is relative,
     *             that is the first character is not a slash, implementations
     *             are expected to apply a search path algorithm to resolve the
     *             relative path to a resource.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @Override
    public Resource getResource(@NotNull String path) {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.getResource(path));
    }

    /**
     * Wraps and returns the {@code Resource} obtained by calling {@code getResource} on the wrapped resource resolver.
     *
     * @param base The base {@link Resource} against which a relative path
     *             argument given by <code>path</code> is resolved. This
     *             parameter may be <code>null</code> if the <code>path</code> is
     *             known to be absolute.
     * @param path The path to the resource object to be loaded. If the path is
     *             relative, i.e. does not start with a slash (<code>/</code>),
     *             the resource relative to the given <code>base</code> resource
     *             is returned. The path may contain relative path specifiers
     *             like <code>.</code> (current location) and <code>..</code>
     *             (parent location), which are resolved by this method.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @Override
    public Resource getResource(Resource base, @NotNull String path) {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.getResource(base, path));
    }

    @NotNull
    @Override
    public String[] getSearchPath() {
        return wrapped.getSearchPath();
    }

    /**
     * Wraps and returns the {@code Iterator} obtained by calling {@code listChildren} on the wrapped resource resolver.
     *
     * @param parent The {@link Resource Resource} whose children are requested.
     * @return a wrapped iterator obtained through the wrapped resource resolver
     */
    @NotNull
    @Override
    public Iterator<Resource> listChildren(@NotNull Resource parent) {
        return new ResourceIteratorWrapper(this, wrapped.listChildren(parent));
    }

    /**
     * Wraps and returns the {@code Resource} obtained by calling {@code getParent} on the wrapped resource resolver.
     *
     * @param child The {@link Resource Resource} whose parent is requested.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @Override
    public Resource getParent(@NotNull Resource child) {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.getParent(child));
    }

    /**
     * Wraps and returns the {@code Iterable} obtained by calling {@code getChildren} on the wrapped resource resolver.
     *
     * @param parent The {@link Resource Resource} whose children are requested.
     * @return a wrapped iterable obtained through the wrapped resource resolver
     */
    @NotNull
    @Override
    public Iterable<Resource> getChildren(@NotNull final Resource parent) {
        final ResourceResolverWrapper resourceResolverWrapper = this;
        return new Iterable<Resource>() {
            @Override
            public Iterator<Resource> iterator() {
                return new ResourceIteratorWrapper(resourceResolverWrapper, wrapped.getChildren(parent).iterator());
            }
        };
    }

    /**
     * Wraps and returns the {@code Iterator} obtained by calling {@code findResources} on the wrapped resource resolver.
     *
     * @param query    The query string to use to find the resources.
     * @param language The language in which the query is formulated. The
     *                 language should always be specified. However for
     *                 compatibility with older version, if no language
     *                 is specified, "xpath" is used.
     * @return a wrapped iterator obtained through the wrapped resource resolver
     */
    @NotNull
    @Override
    public Iterator<Resource> findResources(@NotNull String query, String language) {
        return new ResourceIteratorWrapper(this, wrapped.findResources(query, language));
    }

    @NotNull
    @Override
    public Iterator<Map<String, Object>> queryResources(@NotNull String query, String language) {
        return wrapped.queryResources(query, language);
    }

    @Override
    public boolean hasChildren(@NotNull Resource resource) {
        return wrapped.hasChildren(resource);
    }

    /**
     * Wraps and returns the {@code ResourceResolver} obtained by calling {@code clone} on the wrapped resource resolver.
     *
     * @param authenticationInfo The map or credential data to overlay the
     *                           original credential data with for the creation of a new
     *                           resource resolver. This may be <code>null</code> in which case
     *                           the same credential data is used as was used to create this
     *                           instance.
     * @return a wrapped resource resolver
     */
    @NotNull
    @Override
    public ResourceResolver clone(Map<String, Object> authenticationInfo) throws LoginException {
        ResourceResolver toWrap = wrapped.clone(authenticationInfo);
        return new ResourceResolverWrapper(toWrap);
    }

    @Override
    public boolean isLive() {
        return wrapped.isLive();
    }

    @Override
    public void close() {
        wrapped.close();
    }

    @Override
    public String getUserID() {
        return wrapped.getUserID();
    }

    @NotNull
    @Override
    public Iterator<String> getAttributeNames() {
        return wrapped.getAttributeNames();
    }

    @Override
    public Object getAttribute(@NotNull String name) {
        return wrapped.getAttribute(name);
    }

    @Override
    public void delete(@NotNull Resource resource) throws PersistenceException {
        wrapped.delete(resource);
    }

    /**
     * Wraps the {@code Resource} obtained by calling {@code create} on the wrapped resource resolver.
     *
     * @param parent     The parent resource
     * @param name       The name of the child resource - this is a plain name, not a path!
     * @param properties Optional properties for the resource
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @NotNull
    @Override
    public Resource create(@NotNull Resource parent, @NotNull String name, Map<String, Object> properties) throws PersistenceException {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.create(parent, name, properties));
    }

    @Override
    public void revert() {
        wrapped.revert();
    }

    @Override
    public void commit() throws PersistenceException {
        wrapped.commit();
    }

    @Override
    public boolean hasChanges() {
        return wrapped.hasChanges();
    }

    @Override
    public String getParentResourceType(Resource resource) {
        return wrapped.getParentResourceType(resource);
    }

    @Override
    public String getParentResourceType(String resourceType) {
        return wrapped.getParentResourceType(resourceType);
    }

    @Override
    public boolean isResourceType(Resource resource, String resourceType) {
        return wrapped.isResourceType(resource, resourceType);
    }

    @Override
    public void refresh() {
        wrapped.refresh();
    }

    /**
     * Wraps the {@code Resource} obtained by calling {@code copy} on the wrapped resource resolver.
     *
     * @param srcAbsPath  the path of the resource to be copied.
     * @param destAbsPath the location to which the resource at
     *                    <code>srcAbsPath</code> is to be copied.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @Override
    public Resource copy(String srcAbsPath, String destAbsPath) throws PersistenceException {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.copy(srcAbsPath, destAbsPath));
    }

    /**
     * Wraps the {@code Resource} obtained by calling {@code move} on the wrapped resource resolver.
     *
     * @param srcAbsPath  the path of the resource to be moved.
     * @param destAbsPath the location to which the resource at
     *                    <code>srcAbsPath</code> is to be moved.
     * @return a wrapped resource obtained through the wrapped resource resolver
     */
    @Override
    public Resource move(String srcAbsPath, String destAbsPath) throws PersistenceException {
        return ResourceResolverResourceWrapper.wrap(this, wrapped.move(srcAbsPath, destAbsPath));
    }

    @Override
    public <AdapterType> AdapterType adaptTo(@NotNull Class<AdapterType> type) {
        return wrapped.adaptTo(type);
    }

    /**
     * {@code ResourceWrapper} that overwrites the {@link #getResourceResolver()} to return the {@link ResourceResolverWrapper}.
     */
    private static class ResourceResolverResourceWrapper extends ResourceWrapper {

        private final ResourceResolverWrapper resolver;

        /**
         * Creates a new wrapper instance delegating all method calls to the given {@code resource}.
         *
         * @param resolver the wrapping resource resolver
         * @param resource the wrapped resource
         */
        ResourceResolverResourceWrapper(ResourceResolverWrapper resolver, Resource resource) {
            super(resource);
            this.resolver = resolver;
        }

        /**
         * Returns the wrapping resource resolver from which this resource was obtained.
         *
         * @return the wrapping resource resolver
         */
        @Override
        public ResourceResolver getResourceResolver() {
            return resolver;
        }

        private static Resource wrap(ResourceResolverWrapper resolver, Resource resource) {
            if (resource != null) {
                return new ResourceResolverResourceWrapper(resolver, resource);
            }
            return null;
        }
    }

    /**
     * {@code IteratorWrapper} that wraps every returned {@code Resource} with the {@code ResourceResolverResourceWrapper}.
     *
     * @see ResourceResolverResourceWrapper
     */
    private static class ResourceIteratorWrapper extends IteratorWrapper<Resource> {

        private final ResourceResolverWrapper resolver;

        public ResourceIteratorWrapper(ResourceResolverWrapper resolver, Iterator<Resource> wrappedIterator) {
            super(wrappedIterator);
            this.resolver = resolver;
        }

        @Override
        public Resource next() {
            return ResourceResolverResourceWrapper.wrap(resolver, super.next());
        }
    }
}
