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

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.Nonnull;

import org.apache.commons.collections4.BidiMap;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.path.Path;
import org.apache.sling.resourceresolver.impl.console.ResourceResolverWebConsolePlugin;
import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider;
import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
import org.apache.sling.resourceresolver.impl.mapping.MapEntriesHandler;
import org.apache.sling.resourceresolver.impl.mapping.Mapping;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
import org.apache.sling.serviceusermapping.ServiceUserMapper;
import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The <code>CommonResourceResolverFactoryImpl</code> is a singleton
 * implementing the shared/common functionality of all resource
 * resolver factories.
 */
public class CommonResourceResolverFactoryImpl implements ResourceResolverFactory, MapConfigurationProvider {

    private static final Logger LOG = LoggerFactory.getLogger(CommonResourceResolverFactoryImpl.class);

    /** Helper for the resource resolver. */
    private MapEntriesHandler mapEntries = MapEntriesHandler.EMPTY;

    /** The web console plugin. */
    private ResourceResolverWebConsolePlugin plugin;

    /** The activator */
    private final ResourceResolverFactoryActivator activator;

    /**
     * Thread local holding the resource resolver stack
     */
    private ThreadLocal<Stack<WeakReference<ResourceResolver>>> resolverStackHolder = new ThreadLocal<>();

    /** Flag indicating whether this factory is still active. */
    private final AtomicBoolean isActive = new AtomicBoolean(true);

    /** The reference queue to handle disposing of resource resolver instances. */
    private final ReferenceQueue<ResourceResolver> resolverReferenceQueue = new ReferenceQueue<>();

    /** Map of the ResourceResolverControl's hash code to the references to open resource resolver instances. */
    private final Map<Integer, ResolverReference> refs = new ConcurrentHashMap<>();

    /** Background thread handling disposing of resource resolver instances. */
    private final Thread refQueueThread;

    private boolean logUnclosedResolvers;

    private final Object optionalNamespaceMangler;


    /**
     * Create a new common resource resolver factory.
     */
    public CommonResourceResolverFactoryImpl(final ResourceResolverFactoryActivator activator) {
        this.activator = activator;
        this.logUnclosedResolvers = activator.isLogUnclosedResourceResolvers();
        this.refQueueThread = new Thread("Apache Sling Resource Resolver Finalizer Thread") {

            @Override
            public void run() {
                while (isLive()) {
                    try {
                        final ResolverReference ref = (ResolverReference) resolverReferenceQueue.remove();
                        ref.close();
                    } catch ( final InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        };
        this.refQueueThread.setDaemon(true);
        this.refQueueThread.start();

        // try create namespace mangler
        Object mangler = null;
        if ( this.isMangleNamespacePrefixes() ) {
            try {
                mangler = new JcrNamespaceMangler();
            } catch ( final Throwable t) {
                LOG.info("Unable to create JCR namespace mangler: {}", t.getMessage());
            }
        }
        this.optionalNamespaceMangler = mangler;
    }

    // ---------- Resource Resolver Factory ------------------------------------

    /**
     * @see org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
     */
    @Nonnull
    @Override
    public ResourceResolver getAdministrativeResourceResolver(final Map<String, Object> passedAuthenticationInfo)
    throws LoginException {
        checkIsLive();

        // create a copy of the passed authentication info as we modify the map
        final Map<String, Object> authenticationInfo = new HashMap<>();
        authenticationInfo.put(ResourceProvider.AUTH_ADMIN, Boolean.TRUE);
        if ( passedAuthenticationInfo != null ) {
            authenticationInfo.putAll(passedAuthenticationInfo);
            // make sure there is no leaking of service info props
            // (but the bundle info is passed on as we need it downstream)
            authenticationInfo.remove(SUBSERVICE);
        }

        return getResourceResolverInternal(authenticationInfo, true);
    }

    /**
     * @see org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
     */
    @Nonnull
    @Override
    public ResourceResolver getResourceResolver(final Map<String, Object> passedAuthenticationInfo)
    throws LoginException {
        checkIsLive();

        // create a copy of the passed authentication info as we modify the map
        final Map<String, Object> authenticationInfo = new HashMap<>();
        if ( passedAuthenticationInfo != null ) {
            authenticationInfo.putAll(passedAuthenticationInfo);
            // make sure there is no leaking of service bundle and info props
            authenticationInfo.remove(ResourceProvider.AUTH_SERVICE_BUNDLE);
            authenticationInfo.remove(SUBSERVICE);
        }

        final ResourceResolver result = getResourceResolverInternal(authenticationInfo, false);
        Stack<WeakReference<ResourceResolver>> resolverStack = resolverStackHolder.get();
        if ( resolverStack == null ) {
            resolverStack = new Stack<>();
            resolverStackHolder.set(resolverStack);
        }
        resolverStack.push(new WeakReference<>(result));
        return result;
    }


    /**
     * @see org.apache.sling.api.resource.ResourceResolverFactory#getThreadResourceResolver()
     */
    @Override
    public ResourceResolver getThreadResourceResolver() {
        if (!isLive()) {
            return null;
        }

        ResourceResolver result = null;
        final Stack<WeakReference<ResourceResolver>> resolverStack = resolverStackHolder.get();
        if ( resolverStack != null) {
            while ( result == null && !resolverStack.isEmpty() ) {
                result = resolverStack.peek().get();
                if ( result == null ) {
                    resolverStack.pop();
                }
            }
        }
        return result;
    }

    // ---------- Implementation helpers --------------------------------------

    /**
     * Inform about a new resource resolver instance.
     * We create a weak reference to be able to close the resolver if close on the
     * resource resolver is never called.
     * @param resolver The resource resolver
     * @param ctrl The resource resolver control
     */
    public void register(final ResourceResolver resolver,
            final ResourceResolverControl ctrl) {
        // create new weak reference
        refs.put(ctrl.hashCode(), new ResolverReference(resolver, this.resolverReferenceQueue, ctrl, this));
    }

    /**
     * Inform about a closed resource resolver.
     * Make sure to remove it from the current thread context.
     * @param resourceResolverImpl The resource resolver
     * @param ctrl The resource resolver control
     */
    public void unregister(final ResourceResolver resourceResolverImpl,
            final ResourceResolverControl ctrl) {
        unregisterControl(ctrl);

        // on shutdown, the factory might already be closed before the resolvers close
        // therefore we have to check for null
        final ThreadLocal<Stack<WeakReference<ResourceResolver>>> tl = resolverStackHolder;
        if ( tl != null ) {
            final Stack<WeakReference<ResourceResolver>> resolverStack = tl.get();
            if ( resolverStack != null ) {
                final Iterator<WeakReference<ResourceResolver>> i = resolverStack.iterator();
                while ( i.hasNext() ) {
                    final WeakReference<ResourceResolver> ref = i.next();
                    if ( ref.get() == null || ref.get() == resourceResolverImpl ) {
                        i.remove();
                    }
                }
                if ( resolverStack.isEmpty() ) {
                    tl.remove();
                }
            }
        }
    }

    /**
     * Create a new ResourceResolver
     * @param authenticationInfo The authentication map
     * @param isAdmin is an administrative resolver requested?
     * @return A resource resolver
     * @throws LoginException if login to any of the required resource providers fails.
     */
    ResourceResolver getResourceResolverInternal(final Map<String, Object> authenticationInfo,
                                                        final boolean isAdmin)
            throws LoginException {
        checkIsLive();

        return new ResourceResolverImpl(this, isAdmin, authenticationInfo);
    }

    /**
     * Close a resource resolver control and remove its corresponding
     * resolver reference from the map of weak references.
     *
     * @param ctrl The resource resolver control
     * @return true if the control was closed, false it had been closed before.
     */
    private boolean unregisterControl(final ResourceResolverControl ctrl) {
        // remove reference from the set of weak references and clear
        final ResolverReference reference = refs.remove(ctrl.hashCode());
        if (reference != null) {
            reference.clear();
        }
        final boolean doCloseControl = !ctrl.isClosed();
        if (doCloseControl) {
            ctrl.close();
        }
        return doCloseControl;
    }

    private void checkIsLive() throws LoginException {
        if ( !isLive() ) {
            throw new LoginException("ResourceResolverFactory is deactivated.");
        }
    }

    public MapEntriesHandler getMapEntries() {
        return mapEntries;
    }

    /** Activates this component */
    protected void activate(final BundleContext bundleContext) {
        final Logger logger = LoggerFactory.getLogger(getClass());
        try {
            plugin = new ResourceResolverWebConsolePlugin(bundleContext, this, this.activator.getRuntimeService());
        } catch (final Throwable ignore) {
            // an exception here probably means the web console plugin is not
            // available
            logger.debug("activate: unable to setup web console plugin.", ignore);
        }
        // set up the map entries from configuration
        try {
            mapEntries = new MapEntries(this, bundleContext, this.activator.getEventAdmin());
        } catch (final Exception e) {
            logger.error("activate: Cannot access repository, failed setting up Mapping Support", e);
        }
    }

    /**
     * Deactivates this component
     */
    protected void deactivate() {
        if (!isActive.compareAndSet(true, false)) {
            return;
        }
        this.refQueueThread.interrupt();

        if (plugin != null) {
            plugin.dispose();
            plugin = null;
        }

        if (mapEntries instanceof MapEntries ) {
            ((MapEntries)mapEntries).dispose();
            mapEntries = MapEntries.EMPTY;
        }
        resolverStackHolder = null;

        // copy and clear map before closing the remaining references
        final Collection<ResolverReference> references = new ArrayList<>(refs.values());
        refs.clear();
        for(final ResolverReference ref : references) {
            ref.close();
        }
    }

    public ResourceDecoratorTracker getResourceDecoratorTracker() {
        return this.activator.getResourceDecoratorTracker();
    }

    public String[] getSearchPath() {
        return this.activator.getSearchPath();
    }

    public boolean isMangleNamespacePrefixes() {
        return this.activator.isMangleNamespacePrefixes();
    }

    public Object getNamespaceMangler() {
        return this.optionalNamespaceMangler;
    }

    @Override
    public String getMapRoot() {
        return this.activator.getMapRoot();
    }

    @Override
    public boolean isMapConfiguration(String path) {
        return this.activator.isMapConfiguration(path);
    }

    @Override
    public Mapping[] getMappings() {
        return this.activator.getMappings();
    }

    @Override
    public BidiMap getVirtualURLMap() {
        return this.activator.getVirtualURLMap();
    }

    @Override
    public int getDefaultVanityPathRedirectStatus() {
        return this.activator.getDefaultVanityPathRedirectStatus();
    }

    /**
     * get's the ServiceTracker of the ResourceAccessSecurity service
     */
    public ResourceAccessSecurityTracker getResourceAccessSecurityTracker () {
        return this.activator.getResourceAccessSecurityTracker();
    }

    @Nonnull
    @Override
    public ResourceResolver getServiceResourceResolver(
            final Map<String, Object> authenticationInfo) throws LoginException {
        checkIsLive();

        return getResourceResolverInternal(authenticationInfo, false);
    }

    @Override
    public boolean isVanityPathEnabled() {
        return this.activator.isVanityPathEnabled();
    }

    @Override
    public long getMaxCachedVanityPathEntries() {
        return this.activator.getMaxCachedVanityPathEntries();
    }

    @Override
    public boolean isMaxCachedVanityPathEntriesStartup() {
        return this.activator.isMaxCachedVanityPathEntriesStartup();
    }

    @Override
    public int getVanityBloomFilterMaxBytes() {
        return this.activator.getVanityBloomFilterMaxBytes();
    }

    @Override
    public boolean isOptimizeAliasResolutionEnabled() {
        return this.activator.isOptimizeAliasResolutionEnabled();
    }

    @Override
    public boolean hasVanityPathPrecedence() {
        return this.activator.hasVanityPathPrecedence();
    }

    @Override
    public Path[] getObservationPaths() {
        return this.activator.getObservationPaths();
    }

    @Override
    public List<VanityPathConfig> getVanityPathConfig() {
        final String[] includes = this.activator.getVanityPathWhiteList();
        final String[] excludes = this.activator.getVanityPathBlackList();
        if ( includes == null && excludes == null ) {
            return null;
        }
        final List<VanityPathConfig> configs = new ArrayList<>();
        if ( includes != null ) {
            for(final String val : includes) {
                configs.add(new VanityPathConfig(val, false));
            }
        }
        if ( excludes != null ) {
            for(final String val : excludes) {
                configs.add(new VanityPathConfig(val, true));
            }
        }
        Collections.sort(configs);
        return configs;
    }

    /**
     * Is this factory still alive?
     */
    public boolean isLive() {
        return this.isActive.get();
    }

    public boolean shouldLogResourceResolverClosing() {
        return activator.shouldLogResourceResolverClosing();
    }

    public ResourceProviderTracker getResourceProviderTracker() {
        return activator.getResourceProviderTracker();
    }

    @Override
    public Map<String, Object> getServiceUserAuthenticationInfo(final String subServiceName)
    throws LoginException {
        // get an administrative resource resolver
        // Ensure a mapped user name or principal names: If no user/principal name(s)
        // is/are defined for a bundle
        // acting as a service, the user may be null. We can decide whether
        // this should yield guest access or no access at all. For now
        // no access is granted if there is no service user defined for
        // the bundle.
    	final Bundle bundle = this.activator.getBundleContext().getBundle();

        ServiceUserMapper mapper = this.activator.getServiceUserMapper();
        final Iterable<String> principalNames = mapper.getServicePrincipalNames(bundle, subServiceName);
        final String userName = (principalNames == null) ? mapper.getServiceUserID(bundle, subServiceName) : null;
        if (principalNames == null && userName == null) {
            throw new LoginException("Cannot derive user name or principal names for bundle "
                            + bundle + " and sub service " + subServiceName);
        }

        final Map<String, Object> authenticationInfo = new HashMap<>();
        // ensure proper user name and service bundle
        authenticationInfo.put(ResourceResolverFactory.SUBSERVICE, subServiceName);
        authenticationInfo.put(ResourceProvider.AUTH_SERVICE_BUNDLE, bundle);
        if (userName != null) {
            authenticationInfo.put(ResourceResolverFactory.USER, userName);
        }

        return authenticationInfo;
    }

    /**
     * Extension of a weak reference to be able to get the control object
     * that is used for cleaning up.
     */
    private static final class ResolverReference extends WeakReference<ResourceResolver> {

        private final ResourceResolverControl control;

        private final Exception openingException;

        private final CommonResourceResolverFactoryImpl factory;

        ResolverReference(final ResourceResolver referent,
                          final ReferenceQueue<? super ResourceResolver> q,
                          final ResourceResolverControl ctrl,
                          final CommonResourceResolverFactoryImpl factory) {
            super(referent, q);
            this.control = ctrl;
            this.factory = factory;
            this.openingException = factory.logUnclosedResolvers && LOG.isInfoEnabled() ? new Exception("Opening Stacktrace") : null;
        }

        public void close() {
            try {
                if (factory.unregisterControl(this.control) && factory.logUnclosedResolvers) {
                    if (factory.isLive()) {
                        LOG.warn("Closed unclosed ResourceResolver. The creation stacktrace is available on info log level.");
                    } else {
                        LOG.warn("Forced close of ResourceResolver because the ResourceResolverFactory is shutting down.");
                    }
                    LOG.info("Unclosed ResourceResolver was created here: ", openingException);
                }
            } catch (Throwable t) {
                LOG.warn("Exception while closing ResolverReference", t);
            }
        }
    }
}