/*
 * 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.jcr.resource.internal.helper.jcr;

import java.io.Closeable;
import java.io.IOException;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingException;
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.ResourceResolverFactory;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.external.URIProvider;
import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.resource.api.JcrResourceConstants;
import org.apache.sling.jcr.resource.internal.JcrListenerBaseConfig;
import org.apache.sling.jcr.resource.internal.JcrModifiableValueMap;
import org.apache.sling.jcr.resource.internal.JcrResourceListener;
import org.apache.sling.jcr.resource.internal.NodeUtil;
import org.apache.sling.spi.resource.provider.ObserverConfiguration;
import org.apache.sling.spi.resource.provider.ProviderContext;
import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(name="org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderFactory",
           service = ResourceProvider.class,
           property = {
                   ResourceProvider.PROPERTY_NAME + "=JCR",
                   ResourceProvider.PROPERTY_ROOT + "=/",
                   ResourceProvider.PROPERTY_MODIFIABLE + ":Boolean=true",
                   ResourceProvider.PROPERTY_ADAPTABLE + ":Boolean=true",
                   ResourceProvider.PROPERTY_ATTRIBUTABLE + ":Boolean=true",
                   ResourceProvider.PROPERTY_REFRESHABLE + ":Boolean=true",
                   ResourceProvider.PROPERTY_AUTHENTICATE + "=" + ResourceProvider.AUTHENTICATE_REQUIRED,
                   Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
           })
public class JcrResourceProvider extends ResourceProvider<JcrProviderState> {

    /** Logger */
    private final Logger logger = LoggerFactory.getLogger(JcrResourceProvider.class);

    private static final String REPOSITORY_REFERNENCE_NAME = "repository";

    private static final Set<String> IGNORED_PROPERTIES = new HashSet<String>();
    static {
        IGNORED_PROPERTIES.add(NodeUtil.MIXIN_TYPES);
        IGNORED_PROPERTIES.add(NodeUtil.NODE_TYPE);
        IGNORED_PROPERTIES.add("jcr:created");
        IGNORED_PROPERTIES.add("jcr:createdBy");
    }

    @Reference(name = REPOSITORY_REFERNENCE_NAME, service = SlingRepository.class)
    private ServiceReference<SlingRepository> repositoryReference;

    /** The JCR listener base configuration. */
    private volatile JcrListenerBaseConfig listenerConfig;

    /** The JCR observation listeners. */
    private final Map<ObserverConfiguration, Closeable> listeners = new HashMap<>();

    private final Map<URIProvider, URIProvider> providers = new ConcurrentHashMap<URIProvider, URIProvider>();

    private volatile SlingRepository repository;

    private volatile JcrProviderStateFactory stateFactory;

    private final AtomicReference<DynamicClassLoaderManager> classLoaderManagerReference = new AtomicReference<DynamicClassLoaderManager>();

    private AtomicReference<URIProvider[]> uriProviderReference = new AtomicReference<URIProvider[]>();

    @Activate
    protected void activate(final ComponentContext context) throws RepositoryException {
        SlingRepository repository = context.locateService(REPOSITORY_REFERNENCE_NAME,
                this.repositoryReference);
        if (repository == null) {
            // concurrent unregistration of SlingRepository service
            // don't care, this component is going to be deactivated
            // so we just stop working
            logger.warn("activate: Activation failed because SlingRepository may have been unregistered concurrently");
            return;
        }

        this.repository = repository;

        this.stateFactory = new JcrProviderStateFactory(repositoryReference, repository,
                classLoaderManagerReference, uriProviderReference);
    }

    @Deactivate
    protected void deactivate() {
        this.stateFactory = null;
    }

    @Reference(name = "dynamicClassLoaderManager",
            service = DynamicClassLoaderManager.class,
            cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
    protected void bindDynamicClassLoaderManager(final DynamicClassLoaderManager dynamicClassLoaderManager) {
        this.classLoaderManagerReference.set(dynamicClassLoaderManager);
    }

    protected void unbindDynamicClassLoaderManager(final DynamicClassLoaderManager dynamicClassLoaderManager) {
        this.classLoaderManagerReference.compareAndSet(dynamicClassLoaderManager, null);
    }

    @Reference(
            name = "uriprovider",
            service = URIProvider.class,
            cardinality = ReferenceCardinality.MULTIPLE,
            policy = ReferencePolicy.DYNAMIC,
            bind = "bindUriProvider",
            unbind = "unbindUriProvider"
    )
    private void bindUriProvider(URIProvider uriProvider) {

        providers.put(uriProvider, uriProvider);
        updateURIProviders();
    }
    private void unbindUriProvider(URIProvider uriProvider) {
        providers.remove(uriProvider);
        updateURIProviders();
    }

    private void updateURIProviders() {
        URIProvider[] ups = providers.values().toArray(new URIProvider[providers.size()]);
        this.uriProviderReference.set(ups);
    }

    @Override
    public void start(final ProviderContext ctx) {
        super.start(ctx);
        this.registerListeners();
    }

    @Override
    public void stop() {
        this.unregisterListeners();
        super.stop();
    }

    @Override
    public void update(final long changeSet) {
        super.update(changeSet);
        this.updateListeners();
    }

    @SuppressWarnings("unused")
    private void bindRepository(final ServiceReference<SlingRepository> ref) {
        this.repositoryReference = ref;
        this.repository = null;
    }

    @SuppressWarnings("unused")
    private void unbindRepository(final ServiceReference<SlingRepository> ref) {
        if (this.repositoryReference == ref) {
            this.repositoryReference = null;
            this.repository = null;
        }
    }

    /**
     * Register all observation listeners.
     */
    private void registerListeners() {
        if ( this.repository != null ) {
            logger.debug("Registering resource listeners...");
            try {
                this.listenerConfig = new JcrListenerBaseConfig(this.getProviderContext().getObservationReporter(),
                    this.repository);
                for(final ObserverConfiguration config : this.getProviderContext().getObservationReporter().getObserverConfigurations()) {
                    logger.debug("Registering listener for {}", config.getPaths());
                    final Closeable listener = new JcrResourceListener(this.listenerConfig,
                            config);
                    this.listeners.put(config, listener);
                }
            } catch (final RepositoryException e) {
                throw new SlingException("Can't create the JCR event listener.", e);
            }
            logger.debug("Registered resource listeners");
        }
    }

    /**
     * Unregister all observation listeners.
     */
    private void unregisterListeners() {
        logger.debug("Unregistering resource listeners...");
        for(final Closeable c : this.listeners.values()) {
            try {
                logger.debug("Removing listener for {}", ((JcrResourceListener)c).getConfig().getPaths());
                c.close();
            } catch (final IOException e) {
                // ignore this as the method above does not throw it
            }
        }
        this.listeners.clear();
        if ( this.listenerConfig != null ) {
            try {
                this.listenerConfig.close();
            } catch (final IOException e) {
                // ignore this as the method above does not throw it
            }
            this.listenerConfig = null;
        }
        logger.debug("Unregistered resource listeners");
    }

    /**
     * Update observation listeners.
     */
    private void updateListeners() {
        if ( this.listenerConfig == null ) {
            this.unregisterListeners();
            this.registerListeners();
        } else {
            logger.debug("Updating resource listeners...");
            final Map<ObserverConfiguration, Closeable> oldMap = new HashMap<>(this.listeners);
            this.listeners.clear();
            try {
                for(final ObserverConfiguration config : this.getProviderContext().getObservationReporter().getObserverConfigurations()) {
                    // check if such a listener already exists
                    Closeable listener = oldMap.remove(config);
                    if ( listener == null ) {
                        logger.debug("Registering listener for {}", config.getPaths());
                        listener = new JcrResourceListener(this.listenerConfig, config);
                    } else {
                        logger.debug("Updating listener for {}", config.getPaths());
                        ((JcrResourceListener)listener).update(config);
                    }
                    this.listeners.put(config, listener);
                }
            } catch (final RepositoryException e) {
                throw new SlingException("Can't create the JCR event listener.", e);
            }
            for(final Closeable c : oldMap.values()) {
                try {
                    logger.debug("Removing listener for {}", ((JcrResourceListener)c).getConfig().getPaths());
                    c.close();
                } catch (final IOException e) {
                    // ignore this as the method above does not throw it
                }
            }
            logger.debug("Updated resource listeners");
        }
    }

    /**
     * Create a new ResourceResolver wrapping a Session object. Carries map of
     * authentication info in order to create a new resolver as needed.
     */
    @Override
    @NotNull public JcrProviderState authenticate(final @NotNull Map<String, Object> authenticationInfo)
    throws LoginException {
        return stateFactory.createProviderState(authenticationInfo);
    }

    @Override
    public void logout(final @NotNull JcrProviderState state) {
        state.logout();
    }

    @Override
    public boolean isLive(final @NotNull ResolveContext<JcrProviderState> ctx) {
        return ctx.getProviderState().getSession().isLive();
    }

    @Override
    public Resource getResource(ResolveContext<JcrProviderState> ctx, String path, ResourceContext rCtx, Resource parent) {
        try {
            return ctx.getProviderState().getResourceFactory().createResource(ctx.getResourceResolver(), path, parent, rCtx.getResolveParameters());
        } catch (RepositoryException e) {
            throw new SlingException("Can't get resource", e);
        }
    }

    @Override
    public Iterator<Resource> listChildren(ResolveContext<JcrProviderState> ctx, Resource parent) {
        JcrItemResource<?> parentItemResource;

        // short cut for known JCR resources
        if (parent instanceof JcrItemResource) {
            parentItemResource = (JcrItemResource<?>) parent;
        } else {
            // try to get the JcrItemResource for the parent path to list
            // children
            try {
                parentItemResource = ctx.getProviderState().getResourceFactory().createResource(
                        parent.getResourceResolver(), parent.getPath(), null,
                        parent.getResourceMetadata().getParameterMap());
            } catch (RepositoryException re) {
                throw new SlingException("Can't list children", re);
            }
        }

        // return children if there is a parent item resource, else null
        return (parentItemResource != null)
                ? parentItemResource.listJcrChildren()
                : null;
    }

    @Override
    public @Nullable Resource getParent(final @NotNull ResolveContext<JcrProviderState> ctx, final @NotNull Resource child) {
        if (child instanceof JcrItemResource<?>) {
            try {
                String version = null;
                if (child.getResourceMetadata().getParameterMap() != null) {
                    version = child.getResourceMetadata().getParameterMap().get("v");
                }
                if (version == null) {
                    String parentPath = ResourceUtil.getParent(child.getPath());
                    if (parentPath != null) {
                        Node parentNode = (Node) ctx.getProviderState().getResourceFactory()
                            .getItemOrNull(parentPath);
                        if (parentNode != null) {
                            return new JcrNodeResource(ctx.getResourceResolver(),
                                parentNode.getPath(), null, parentNode,
                                ctx.getProviderState().getHelperData());
                        }
                    }
                    return null;
                }
            } catch (RepositoryException e) {
                logger.warn("Can't get parent for {}", child, e);
                return null;
            }
        }
        return super.getParent(ctx, child);
    }

    @Override
    public Collection<String> getAttributeNames(final @NotNull ResolveContext<JcrProviderState> ctx) {
        final Set<String> names = new HashSet<String>();
        final String[] sessionNames = ctx.getProviderState().getSession().getAttributeNames();
        for(final String name : sessionNames) {
            if ( isAttributeVisible(name) ) {
                names.add(name);
            }
        }
        return names;
    }

    @Override
    public Object getAttribute(final @NotNull ResolveContext<JcrProviderState> ctx, final @NotNull String name) {
        if (isAttributeVisible(name)) {
            if (ResourceResolverFactory.USER.equals(name)) {
                return ctx.getProviderState().getSession().getUserID();
            }
            return ctx.getProviderState().getSession().getAttribute(name);
        }
        return null;
    }

    @Override
    public Resource create(final @NotNull ResolveContext<JcrProviderState> ctx, final String path, final Map<String, Object> properties)
    throws PersistenceException {
        // check for node type
        final Object nodeObj = (properties != null ? properties.get(NodeUtil.NODE_TYPE) : null);
        // check for sling:resourcetype
        final String nodeType;
        if ( nodeObj != null ) {
            nodeType = nodeObj.toString();
        } else {
            final Object rtObj =  (properties != null ? properties.get(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY) : null);
            boolean isNodeType = false;
            if ( rtObj != null ) {
                final String resourceType = rtObj.toString();
                if ( resourceType.indexOf(':') != -1 && resourceType.indexOf('/') == -1 ) {
                    try {
                        ctx.getProviderState().getSession().getWorkspace().getNodeTypeManager().getNodeType(resourceType);
                        isNodeType = true;
                    } catch (final RepositoryException ignore) {
                        // we expect this, if this isn't a valid node type, therefore ignoring
                    }
                }
            }
            if ( isNodeType ) {
                nodeType = rtObj.toString();
            } else {
                nodeType = null;
            }
        }
        final String jcrPath = path;
        if ( jcrPath == null ) {
            throw new PersistenceException("Unable to create node at " + path, null, path, null);
        }
        Node node = null;
        try {
            final int lastPos = jcrPath.lastIndexOf('/');
            final Node parent;
            if ( lastPos == 0 ) {
                parent = ctx.getProviderState().getSession().getRootNode();
            } else {
                parent = (Node) ctx.getProviderState().getSession().getItem(jcrPath.substring(0, lastPos));
            }
            final String name = jcrPath.substring(lastPos + 1);
            if ( nodeType != null ) {
                node = parent.addNode(name, nodeType);
            } else {
                node = parent.addNode(name);
            }

            if ( properties != null ) {
                // create modifiable map
                final JcrModifiableValueMap jcrMap = new JcrModifiableValueMap(node, ctx.getProviderState().getHelperData());
                // check mixin types first
                final Object value = properties.get(NodeUtil.MIXIN_TYPES);
                if ( value != null ) {
                    jcrMap.put(NodeUtil.MIXIN_TYPES, value);
                }
                for(final Map.Entry<String, Object> entry : properties.entrySet()) {
                    if ( !IGNORED_PROPERTIES.contains(entry.getKey()) ) {
                        try {
                            jcrMap.put(entry.getKey(), entry.getValue());
                        } catch (final IllegalArgumentException iae) {
                            try {
                                node.remove();
                            } catch ( final RepositoryException re) {
                                // we ignore this
                            }
                            throw new PersistenceException(iae.getMessage(), iae, path, entry.getKey());
                        }
                    }
                }
            }

            return new JcrNodeResource(ctx.getResourceResolver(), path, null, node, ctx.getProviderState().getHelperData());
        } catch (final RepositoryException e) {
            throw new PersistenceException("Unable to create node at " + jcrPath, e, path, null);
        }
    }

    @Override
    public void delete(final @NotNull ResolveContext<JcrProviderState> ctx, final @NotNull Resource resource)
    throws PersistenceException {
        // try to adapt to Item
        Item item = resource.adaptTo(Item.class);
        try {
            if ( item == null ) {
                final String jcrPath = resource.getPath();
                if (jcrPath == null) {
                    logger.debug("delete: {} maps to an empty JCR path", resource.getPath());
                    throw new PersistenceException("Unable to delete resource", null, resource.getPath(), null);
                }
                item = ctx.getProviderState().getSession().getItem(jcrPath);
            }
            item.remove();
        } catch (final RepositoryException e) {
            throw new PersistenceException("Unable to delete resource", e, resource.getPath(), null);
        }
    }

    @Override
    public void revert(final @NotNull ResolveContext<JcrProviderState> ctx) {
        try {
            ctx.getProviderState().getSession().refresh(false);
        } catch (final RepositoryException ignore) {
            logger.warn("Unable to revert pending changes.", ignore);
        }
    }

    @Override
    public void commit(final @NotNull ResolveContext<JcrProviderState> ctx)
    throws PersistenceException {
        try {
            ctx.getProviderState().getSession().save();
        } catch (final RepositoryException e) {
            throw new PersistenceException("Unable to commit changes to session.", e);
        }
    }

    @Override
    public boolean hasChanges(final @NotNull ResolveContext<JcrProviderState> ctx) {
        try {
            return ctx.getProviderState().getSession().hasPendingChanges();
        } catch (final RepositoryException ignore) {
            logger.warn("Unable to check session for pending changes.", ignore);
        }
        return false;
    }

    @Override
    public void refresh(final @NotNull ResolveContext<JcrProviderState> ctx) {
        try {
            ctx.getProviderState().getSession().refresh(true);
        } catch (final RepositoryException ignore) {
            logger.warn("Unable to refresh session.", ignore);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public @Nullable <AdapterType> AdapterType adaptTo(final @NotNull ResolveContext<JcrProviderState> ctx,
            final @NotNull Class<AdapterType> type) {
        Session session = ctx.getProviderState().getSession();
        if (type == Session.class) {
            return (AdapterType) session;
        } else if (type == Principal.class) {
            try {
                if (session instanceof JackrabbitSession && session.getUserID() != null) {
                    JackrabbitSession s =((JackrabbitSession) session);
                    final UserManager um = s.getUserManager();
                    if (um != null) {
                        final Authorizable auth = um.getAuthorizable(s.getUserID());
                        if (auth != null) {
                            return (AdapterType) auth.getPrincipal();
                        }
                    }
                }
                logger.debug("not able to adapto Resource to Principal, let the base class try to adapt");
            } catch (RepositoryException e) {
                logger.warn("error while adapting Resource to Principal, let the base class try to adapt", e);
            }
        }
        return super.adaptTo(ctx, type);
    }

    @Override
    public boolean copy(final  @NotNull ResolveContext<JcrProviderState> ctx,
            final String srcAbsPath,
            final String destAbsPath) throws PersistenceException {
        return false;
    }

    @Override
    public boolean move(final  @NotNull ResolveContext<JcrProviderState> ctx,
            final String srcAbsPath,
            final String destAbsPath) throws PersistenceException {
        final String srcNodePath = srcAbsPath;
        final String dstNodePath = destAbsPath + '/' + ResourceUtil.getName(srcAbsPath);
        try {
            ctx.getProviderState().getSession().move(srcNodePath, dstNodePath);
            return true;
        } catch (final RepositoryException e) {
            throw new PersistenceException("Unable to move resource to " + destAbsPath, e, srcAbsPath, null);
        }
    }

    @Override
    public @Nullable QueryLanguageProvider<JcrProviderState> getQueryLanguageProvider() {
        final ProviderContext ctx = this.getProviderContext();
        if ( ctx != null ) {
            return new BasicQueryLanguageProvider(ctx);
        }
        return null;
    }

    /**
     * Returns <code>true</code> unless the name is
     * <code>user.jcr.credentials</code> (
     * {@link JcrResourceConstants#AUTHENTICATION_INFO_CREDENTIALS}) or contains
     * the string <code>password</code> as in <code>user.password</code> (
     * {@link org.apache.sling.api.resource.ResourceResolverFactory#PASSWORD})
     *
     * @param name The name to check whether it is visible or not
     * @return <code>true</code> if the name is assumed visible
     * @throws NullPointerException if <code>name</code> is <code>null</code>
     */
    private static boolean isAttributeVisible(final String name) {
        return !name.equals(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS)
            && !name.contains("password");
    }
}
