/*
 * 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.spi.resource.provider;

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

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

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.ResourceUtil;
import org.osgi.annotation.versioning.ConsumerType;

/**
 * API for providers of resources. Used by the {@link ResourceResolver} to
 * transparently access resources from different locations such as a JCR
 * repository, a database, or bundle resources.
 * <p>
 * This extension point is defined by an abstract class (in contrast to
 * an interface) as this allows to add new functionality in new versions
 * without breaking any implementation.
 * <p>
 * This service is intended to be implemented by providers of resource
 * instances on behalf of the {@link ResourceResolver}. It
 * is not intended to be used by client applications directly. A resource
 * provider implements this service by extending this class.
 * <p>
 * A resource provider must set the {@link #PROPERTY_ROOT} property with an
 * absolute path. This is the mount point of the resource provider. If there
 * is more than one provider registering for the same root, only the one
 * with the highest service ranking is used.
 * <p>
 * If a provider is used in the resource tree, it gets activated through
 * a call of the {@link #start(ProviderContext)} method. If the
 * provider is not used anymore within the resource tree, the
 * {@link #stop()} method is called. Whenever
 * information concerning the provider is changed while the provider
 * is used, the {@link #update(long)} method is called. The provider context
 * instance which is passed to the {@link #start(ProviderContext)} method
 * contains the updated state.
 * <p>
 * Some resource providers might require (user) authentication. For example
 * the JCR resource provider uses authenticated sessions. If a provider
 * requires authentication it must indicate this by setting the service
 * registration property {@link #PROPERTY_AUTHENTICATE} to either
 * {@link #AUTHENTICATE_LAZY} or {@link #AUTHENTICATE_REQUIRED}. In these
 * cases, the resource resolver calls {@link #authenticate(Map)} and on
 * successful authentication the provider returns a state object for
 * the current user. This object is passed into the provider with
 * every method through {@link ResolveContext#getProviderState()}.
 * If a provider requires authentication, the {@link #logout(Object)} method
 * is called, when the resource resolver is closed. If the provider
 * does not set this service property or sets it to {@link #AUTHENTICATE_NO}
 * the {@link #authenticate(Map)} and {@link #logout(Object)} method
 * are never called and therefore {@link ResolveContext#getProviderState()}
 * will return {@code null}.
 * <p>
 * Each method gets the {@link ResourceContext} which gives access to
 * further functionality.
 *
 * @since 1.0.0 (Sling API Bundle 2.11.0)
 */
@ConsumerType
public abstract class ResourceProvider<T> {

    /**
     * The name of the service registration property containing the root path
     * of the resources provided by this provider.
     * If this property is missing, empty or invalid, the provider is ignored.
     * (value is "provider.root")
     */
    public static final String PROPERTY_ROOT = "provider.root";

    /**
     * Optional service registration property setting a name for the provider.
     * The name must not be unique. The name in combination with the root
     * can be used to identify a resource provider.
     */
    public static final String PROPERTY_NAME = "provider.name";

    /**
     * The name of the service registration property containing a boolean
     * flag indicating if the ResourceAccessSecurity service should be used for
     * this provider or not. ResourceAccessSecurity should only be used if the
     * underlying storage does not provide access control
     * The default for this value is {@code false}.
     * (value is "provider.useResourceAccessSecurity")
     */
    public static final String PROPERTY_USE_RESOURCE_ACCESS_SECURITY = "provider.useResourceAccessSecurity";

    /**
     * Default value for {@link #PROPERTY_AUTHENTICATE}
     * @see #PROPERTY_AUTHENTICATE
     */
    public static final String AUTHENTICATE_NO = "no";

    /**
     * Value for {@link #PROPERTY_AUTHENTICATE} indicating authentication is required.
     * @see #PROPERTY_AUTHENTICATE
     */
    public static final String AUTHENTICATE_REQUIRED = "required";

    /**
     * Value for {@link #PROPERTY_AUTHENTICATE} indicating authentication is needed
     * and will be done on demand.
     * @see #PROPERTY_AUTHENTICATE
     */
    public static final String AUTHENTICATE_LAZY = "lazy";

    /**
     * If a resource provider needs the user to be authenticated this property must be set
     * to either {@link #AUTHENTICATE_LAZY} or {@link #AUTHENTICATE_REQUIRED}.
     * If it is set to {@link #AUTHENTICATE_REQUIRED}, the {@link #authenticate(Map)} method
     * is called when the resource resolver is created and only if authentication against
     * all resource providers marked as required is successful, a resource resolver is
     * created. Otherwise the creation fails.
     * If a provider sets this property to {@link #AUTHENTICATE_LAZY}, the authenticate method
     * is only invoked if a resource from this provider is requested. This might also happen
     * for traversal or queries. If the authentication fails, resources from this provider
     * are not accessible.
     * If this property is not set or set to {@link #AUTHENTICATE_NO}, no authentication
     * is required for this provider and the {@link #authenticate(Map)} is never invoked.
     * String service property, default value is {@link #AUTHENTICATE_NO}.
     * (value is "provider.authenticate")
     */
    public static final String PROPERTY_AUTHENTICATE = "provider.authenticate";

    /**
     * A modifiable resource provider is capable of creating, changing and deleting resources.
     * This means the methods {@link #create(ResolveContext, String, Map)},
     * {@link #delete(ResolveContext, Resource)} and adapting a resource to a modifiable
     * value map is supported.
     * If this flag is set to {@code false}, the resource resolver does not take this
     * provider into account for modifications and modification operations to this provider
     * always result in an exception.
     * If this is set to {@code true}, the property {@link ResourceProvider#PROPERTY_AUTHENTICATE}
     * must require authentication, otherwise this provider registration is considered
     * invalid and the provider is not used.
     * Boolean service property, default value is {@code false}.
     * (value is "provider.modifiable")
     */
    public static final String PROPERTY_MODIFIABLE = "provider.modifiable";

    /**
     * If this flag is set to {@code true}, the resource resolver will use this provider
     * for the adaptTo() operation.
     * Boolean service property, default value is {@code false}.
     * (value is "provider.adaptable")
     */
    public static final String PROPERTY_ADAPTABLE = "provider.adaptable";

    /**
     * If this flag is set to {@code true}, the resource resolver will call {@link #refresh(ResolveContext)}
     * when it's refreshed itself.
     * Boolean service property, default value is {@code false}.
     * (value is "provider.refreshable")
     */
    public static final String PROPERTY_REFRESHABLE = "provider.refreshable";

    /**
     * If this flag is set to {@code true}, the resource resolver will try to get the attribute
     * names and the attribute values from this provider.
     * Boolean service property, default value is {@code false}.
     * (value is "provider.attributable")
     */
    public static final String PROPERTY_ATTRIBUTABLE = "provider.attributable";

    /**
     * The authentication information property referring to the bundle
     * providing a service for which a resource provider is to be retrieved. If
     * this property is provided, the
     * {@link ResourceResolverFactory#SUBSERVICE} property may also be
     * present.
     * <p>
     * {@link ResourceResolverFactory} implementations must provide this
     * property if their implementation of the
     * {@link ResourceResolverFactory#getServiceResourceResolver(Map)} method
     * use a resource provider factory.
     * <p>
     * The type of this property, if present, is
     * {@code org.osgi.framework.Bundle}.
     */
    public static final String AUTH_SERVICE_BUNDLE = "sling.service.bundle";

    /**
     * The authentication information property indicating to use an
     * administrative login. This property must be set of the resource
     * resolver is created through {@link ResourceResolverFactory#getAdministrativeResourceResolver(Map)}.
     */
    public static final String AUTH_ADMIN = "provider.auth.admin";

    /**
     * The resource type be set on resources returned by the
     * {@link #listChildren(ResolveContext, Resource)} method to enable traversing the
     * resource
     * tree down to a deeply nested provided resource which has no concrete
     * parent hierarchy (value is"sling:syntheticResourceProviderResource").
     *
     * @see #listChildren(ResolveContext, Resource)
     */
    public static final String RESOURCE_TYPE_SYNTHETIC = "sling:syntheticResourceProviderResource";

    /** The context for this provider. */
    private volatile ProviderContext ctx;

    /**
     * With a call to this method, the provider implementation is notified that
     * it is used in the resource tree.
     * @param ctx The context for this provider.
     */
    public void start(@Nonnull ProviderContext ctx) {
        this.ctx = ctx;
    }

    /**
     * With a call to this method, the provider implementation is notified
     * that it is not used anymore in the resource tree.
     */
    public void stop() {
        this.ctx = null;
    }

    /**
     * With a call to this method, the provider implementation is notified
     * that any information regarding the registration of the provider
     * has changed. For example, observation listeners might have changed.
     * This method is only called while the provider is used in the resource
     * tree.
     * @param changeSet A bit set of provider info that has changed.
     * @see ProviderContext#OBSERVATION_LISTENER_CHANGED
     * @see ProviderContext#EXCLUDED_PATHS_CHANGED
     */
    public void update(final long changeSet) {
        // nothing to do here
    }

    /**
     * Get the current provider context.
     * @return The provider context or {@code null} if the provider is currently
     *         not used in the resource tree.
     */
    protected @CheckForNull ProviderContext getProviderContext() {
        return this.ctx;
    }

    /**
     * Authenticate against the resource provider.
     * <p>
     * Returns a provider context object if authentication is successful. The
     * context object is passed to the resource provider in all messages through
     * the {@link ResourceContext}. A valid implementation might return {@code null}
     * as the context information.
     * <p>
     * If authentication fails a {@code LoginException} must be thrown.
     * <p>
     * The returned context object grants access to the provided resources with
     * privileges assigned to the service provided by the calling bundle.
     * <p>
     * The {@code authenticationInfo} map will in general contain the same
     * information as provided to the respective {@link ResourceResolver}
     * method. For
     * <p>
     * The provided {@code authenticationInfo} map may be used to provide
     * additional information such as the {@link #AUTH_SERVICE_BUNDLE}.
     * If this property is provided, additional information like
     * {@link ResourceResolverFactory#SUBSERVICE} might be provided, but the
     * {@link ResourceResolverFactory#USER} and {@link ResourceResolverFactory#PASSWORD}
     * properties provided in the map must be ignored.
     * <p>
     * The {@link ResourceResolverFactory#USER_IMPERSONATION} property is obeyed but requires that the
     * authenticated user has permission to impersonate as the requested user.
     * If such permission is missing, a {@code LoginException} is thrown.
     * <p>
     * The resource resolver implementation will call the {@link #logout(Object)}
     * method once the resource resolver is closed. However, if the resource
     * provider is already unregistered when the resource resolver is closed,
     * logout can't be called. Therefore the returned state object might
     * implement {@link java.io.Closeable}. In this case close is called
     * on the state object.
     *
     * @param authenticationInfo A map of further credential information which
     *            may be used by the implementation to parameterize how the
     *            resource resolver is created.
     * @return A context data object according to the
     *         {@code authenticationInfo}.
     * @throws LoginException If an error occurs authenticating with the
     *            provided credential data.
     *
     * @see <a
     *      href="http://sling.apache.org/documentation/the-sling-engine/service-authentication.html">Service
     *      Authentication</a>
     */
    public @CheckForNull T authenticate(final @Nonnull Map<String, Object> authenticationInfo)
    throws LoginException {
        return null;
    }

    /**
     * If the provider requires authentication, this method is called with the state of the user
     * returned by {@link #authenticate(Map)} once the resource resolver is closed.
     *
     * @param state The provider state returned by {@link #authenticate(Map)}.
     */
    public void logout(final @CheckForNull T state) {
        // do nothing
    }

    /**
     * The provider is updated to reflect the latest state.
     * Resources which have changes pending are not discarded.
     * {@link #revert(ResolveContext)} can be called to discard changes.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_REFRESHABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     */
    public void refresh(final @Nonnull ResolveContext<T> ctx) {
        // nothing to do here
    }

    /**
     * Returns {@code true} if this resource provider has not been closed
     * yet and can still be used.
     * <p>
     * This method will never throw an exception
     * even after the resource provider has been closed
     * <p>
     * This method is only called for resource providers which have a state and
     * require authentication.
     *
     * @param ctx The {@link ResolveContext}.
     * @return {@code true} if the resource provider has not been closed
     *         yet and is still active.. Once the resource provider has been closed
     *         or is not active anymore, this method returns {@code false}.
     */
    public boolean isLive(final @Nonnull ResolveContext<T> ctx) {
        return true;
    }

    /**
     * Returns the parent resource from this resource provider or {@code null} if
     * the resource provider cannot find it.
     *
     * The resource provider must not return cached instances for a resource as
     * the resource resolver will update the resource meta data of the resource
     * at the end of the resolution process and this meta data might be different
     * depending on the full path of resource resolution passed into the
     * resource resolver.
     *
     * @param ctx The {@link ResolveContext}.
     * @param child The child resource.
     * @return {@code null} if this provider does not have a resource for
     *         the parent.
     * @throws org.apache.sling.api.SlingException
     *             may be thrown in case of any problem creating the {@code Resource} instance.
     */
    public @CheckForNull Resource getParent(final @Nonnull ResolveContext<T> ctx, final @Nonnull Resource child) {
        final String parentPath = ResourceUtil.getParent(child.getPath());
        if (parentPath == null) {
            return null;
        }
        return this.getResource(ctx, parentPath, ResourceContext.EMPTY_CONTEXT, null);
    }

    /**
     * Returns a resource from this resource provider or {@code null} if
     * the resource provider cannot find it. The path must have the {@link #PROPERTY_ROOT}
     * strings as its prefix.
     *
     * The resource provider must not return cached instances for a resource as
     * the resource resolver will update the resource meta data of the resource
     * at the end of the resolution process and this meta data might be different
     * depending on the full path of resource resolution passed into the
     * resource resolver.
     *
     * @param ctx The {@link ResolveContext}.
     * @param path The full path of the resource.
     * @param resourceContext Additional information for resolving the resource
     * @param parent Optional parent resource
     * @return {@code null} If this provider does not have a resource for
     *         the path.
     * @throws org.apache.sling.api.SlingException
     *             may be thrown in case of any problem creating the {@code Resource} instance.
     */
    public abstract @CheckForNull Resource getResource(@Nonnull final ResolveContext<T> ctx,
            @Nonnull final String path,
            @Nonnull final ResourceContext resourceContext,
            @CheckForNull final Resource parent);

    /**
     * Returns an {@code Iterator} of {@link Resource} objects loaded from
     * the children of the given {@code Resource}. The returned {@link Resource} instances
     *  are attached to the same
     * {@link ResourceResolver} as the given {@code parent} resource.
     * <p>
     * This method may be called for resource providers whose root path list contains a path such
     * that the resource path is a
     * prefix of the list entry. This allows for the enumeration of deeply nested provided resources
     * for which no actual parent
     * hierarchy exists.
     * <p>
     * The returned iterator may in turn contain resources which do not actually exist but are required
     *  to traverse the resource
     * tree. Such resources SHOULD be {@link SyntheticResource} objects whose resource type MUST be set to
     * {@link #RESOURCE_TYPE_SYNTHETIC}.
     *
     * As with {@link #getResource(ResolveContext, String, ResourceContext, Resource)} the returned Resource objects must
     * not be cached objects.
     *
     * @param ctx The {@link ResolveContext}.
     * @param parent
     *            The {@link Resource Resource} whose children are requested.
     * @return An {@code Iterator} of {@link Resource} objects or {@code null} if the resource
     *         provider has no children for the given resource.
     * @throws NullPointerException
     *             If {@code parent} is {@code null}.
     * @throws SlingException
     *             If any error occurs acquiring the child resource iterator.
     */
    public abstract @CheckForNull Iterator<Resource> listChildren(final @Nonnull ResolveContext<T> ctx, final @Nonnull Resource parent);

    /**
     * Returns a collection of attribute names whose value can be retrieved
     * calling the {@link #getAttribute(ResolveContext, String)} method.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_ATTRIBUTABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @return A collection of attribute names or {@code null}
     * @throws IllegalStateException if this resource provider has already been
     *                               closed.
     */
    public @CheckForNull Collection<String> getAttributeNames(final @Nonnull ResolveContext<T> ctx) {
        return null;
    }

    /**
     * Returns the value of the given resource provider attribute or {@code null}
     * if the attribute is not set or not visible (as e.g. security
     * sensitive attributes).
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_ATTRIBUTABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @param name  The name of the attribute to access
     * @return The value of the attribute or {@code null} if the attribute
     *         is not set or not accessible.
     * @throws IllegalStateException
     *             if this resource provider has already been closed.
     */
    public @CheckForNull Object getAttribute(final @Nonnull ResolveContext<T> ctx, final @Nonnull String name) {
        return null;
    }

    /**
     * Create a new resource at the given path.
     * The new resource is put into the transient space of this provider
     * until {@link #commit(ResolveContext)} is called.
     * <p>
     * A resource provider must value {@link ResourceResolver#PROPERTY_RESOURCE_TYPE}
     * to set the resource type of a resource.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @param path The resource path.
     * @param properties Optional properties
     * @return The new resource.
     *
     * @throws PersistenceException If anything fails
     */
    public @Nonnull Resource create(final @Nonnull ResolveContext<T> ctx, final String path, final Map<String, Object> properties)
    throws PersistenceException {
        throw new PersistenceException("create is not supported.");
    }

    /**
     * Delete the resource at the given path.
     * This change is kept in the transient space of this provider
     * until {@link #commit(ResolveContext)} is called.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @param resource The resource to delete.
     *
     * @throws PersistenceException If anything fails
     */
    public void delete(final @Nonnull ResolveContext<T> ctx, final @Nonnull Resource resource)
    throws PersistenceException {
        throw new PersistenceException("delete is not supported.");
    }

    /**
     * Revert all transient changes: create, delete and updates.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     */
    public void revert(final @Nonnull ResolveContext<T> ctx) {
        // nothing to do here
    }

    /**
     * Commit all transient changes: create, delete and updates
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @throws PersistenceException If anything fails
     */
    public void commit(final @Nonnull ResolveContext<T> ctx)
    throws PersistenceException {
        // nothing to do here
    }

    /**
     * Are there any transient changes?
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @return {@code true} if there are pending changes.
     */
    public boolean hasChanges(final @Nonnull ResolveContext<T> ctx) {
        return false;
    }

    /**
     * Get the optional query language provider.
     * If the provider supports this kind of query, it must return a query provider implementation
     * if the provider is active. It should not return a query provider if it is not
     * active.
     * This method is called for each query, therefore the provider implementation
     * might cache the provider object.
     *
     * @return A query language provider if this resource provider supports this type of querying.
     */
    public @CheckForNull QueryLanguageProvider<T> getQueryLanguageProvider() {
        return null;
    }

    /**
     * Adapts the provider to another type.
     * <p>
     * Please not that it is explicitly left as an implementation detail whether
     * each call to this method with the same {@code type} yields the same
     * object or a new object on each call.
     * <p>
     * Implementations of this method should document their adapted types as
     * well as their behavior with respect to returning newly created or not
     * instance on each call.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_ADAPTABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @param <AdapterType> The generic type to which this resource is adapted to.
     * @param type The generic type to which this resource is adapted to.
     * @return The adapter target or {@code null} if the provider cannot
     *         be adapt to the requested type.
     */
    public @CheckForNull <AdapterType> AdapterType adaptTo(final  @Nonnull ResolveContext<T> ctx,
            final @Nonnull Class<AdapterType> type) {
        return null;
    }

    /**
     * This method copies the subgraph rooted at, and including, the resource at
     * {@code srcAbsPath} to the new location at {@code destAbsPath} and
     * adds it as a child node of the resource at {@code destAbsPath}.
     * <p>
     * Both resources are resources from this provider and the full tree is
     * provided by this provider as well.
     * <p>
     * The resource at {@code destAbsPath} needs to exist, if not a {@code PersistenceException}
     * is thrown. If a child resource with the same name already exists at {@code destAbsPath}
     * a {@code PersistenceException} is thrown.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @param srcAbsPath  the path of the resource to be copied.
     * @param destAbsPath the location to which the resource at
     *                    {@code srcAbsPath} is to be copied.
     * @throws PersistenceException If an error occurs.
     * @return {@code true} if the provider can perform the copy
     */
    public boolean copy(final  @Nonnull ResolveContext<T> ctx,
              final @Nonnull String srcAbsPath,
              final @Nonnull String destAbsPath) throws PersistenceException {
        return false;
    }

    /**
     * This method moves the subgraph rooted at, and including, the resource at
     * {@code srcAbsPath} to the new location at {@code destAbsPath} and
     * adds it as a child node of the resource at {@code destAbsPath}.
     * <p>
     * Both resources are resources from this provider and the full tree is
     * provided by this provider as well.
     * <p>
     * The resource at {@code destAbsPath} needs to exist, if not a {@code PersistenceException}
     * is thrown. If a child resource with the same name already exists at {@code destAbsPath}
     * a {@code PersistenceException} is thrown.
     * <p>
     * This method is only called if the provider supports this and indicates
     * it by setting the {@link #PROPERTY_MODIFIABLE} to the value {@code true}.
     *
     * @param ctx The {@link ResolveContext}.
     * @param srcAbsPath  the path of the resource to be copied.
     * @param destAbsPath the location to which the resource at
     *                    {@code srcAbsPath} is to be moved.
     * @throws PersistenceException If an error occurs.
     * @return {@code true} if the provider can perform the move
     */
    public boolean move(final  @Nonnull ResolveContext<T> ctx,
              final @Nonnull String srcAbsPath,
              final @Nonnull String destAbsPath) throws PersistenceException {
        return false;
    }
}
