/*
 * 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.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.TreeBidiMap;
import org.apache.sling.api.resource.ResourceDecorator;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.mapping.PathToUriMappingService;
import org.apache.sling.api.resource.path.Path;
import org.apache.sling.api.resource.runtime.RuntimeService;
import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
import org.apache.sling.resourceresolver.impl.mapping.Mapping;
import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider;
import org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ChangeListener;
import org.apache.sling.resourceresolver.impl.providers.RuntimeServiceImpl;
import org.apache.sling.serviceusermapping.ServiceUserMapper;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
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.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The <code>ResourceResolverFactoryActivator/code> keeps track of required services for the
 * resource resolver factory.
 * One all required providers and provider factories are available a resource resolver factory
 * is registered.
 *
 */
@Designate(ocd = ResourceResolverFactoryConfig.class)
@Component(name = "org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl")
public class ResourceResolverFactoryActivator {


    private static final class FactoryRegistration {
        /** Registration .*/
        public volatile ServiceRegistration<ResourceResolverFactory> factoryRegistration;

        /** Runtime registration. */
        public volatile ServiceRegistration<RuntimeService> runtimeRegistration;

        public volatile CommonResourceResolverFactoryImpl commonFactory;
    }


    /** Logger. */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /** Tracker for the resource decorators. */
    private final ResourceDecoratorTracker resourceDecoratorTracker = new ResourceDecoratorTracker();

    /** all mappings */
    private volatile Mapping[] mappings;

    /** The fake URLs */
    private volatile BidiMap virtualURLMap;

    /** the search path for ResourceResolver.getResource(String) */
    private volatile List<String> searchPath = Collections.emptyList();

    /** the root location of the /etc/map entries */
    private volatile String mapRoot;

    private volatile String mapRootPrefix;

    /** Event admin. */
    @Reference
    EventAdmin eventAdmin;

    /** String Interpolation Provider. */
    @Reference
    StringInterpolationProvider stringInterpolationProvider;

    /** Service User Mapper */
    @Reference
    ServiceUserMapper serviceUserMapper;

    @Reference
    ResourceAccessSecurityTracker resourceAccessSecurityTracker;

    @Reference
    PathToUriMappingService pathToUriMappingService;

    volatile ResourceProviderTracker resourceProviderTracker;

    volatile ResourceChangeListenerWhiteboard changeListenerWhiteboard;

    /** Bundle Context */
    private volatile BundleContext bundleContext;

    private volatile ResourceResolverFactoryConfig config = DEFAULT_CONFIG;

    /** Vanity path whitelist */
    private volatile String[] vanityPathWhiteList;

    /** Vanity path blacklist */
    private volatile String[] vanityPathBlackList;

    /** Observation paths */
    private volatile Path[] observationPaths;

    private final FactoryPreconditions preconds = new FactoryPreconditions();

    /** Factory registration. */
    private volatile FactoryRegistration factoryRegistration;

    /**
     * Get the resource decorator tracker.
     */
    public ResourceDecoratorTracker getResourceDecoratorTracker() {
        return this.resourceDecoratorTracker;
    }

    public ResourceAccessSecurityTracker getResourceAccessSecurityTracker() {
        return this.resourceAccessSecurityTracker;
    }

    public PathToUriMappingService getPathToUriMappingService() {
        return this.pathToUriMappingService;
    }

    public EventAdmin getEventAdmin() {
        return this.eventAdmin;
    }

    public StringInterpolationProvider getStringInterpolationProvider() {
        return stringInterpolationProvider;
    }

    /**
     * This method is called from {@link MapEntries}
     */
    public BidiMap getVirtualURLMap() {
        return virtualURLMap;
    }

    /**
     * This method is called from {@link MapEntries}
     */
    public Mapping[] getMappings() {
        return mappings;
    }

    public List<String> getSearchPath() {
        return searchPath;
    }

    public boolean isMangleNamespacePrefixes() {
        return config.resource_resolver_manglenamespaces();

    }

    public String getMapRoot() {
        return mapRoot;
    }

    public boolean isMapConfiguration(String path) {
        return path.equals(this.mapRoot)
               || path.startsWith(this.mapRootPrefix);
    }

    public int getDefaultVanityPathRedirectStatus() {
        return config.resource_resolver_default_vanity_redirect_status();
    }

    public boolean isVanityPathEnabled() {
        return this.config.resource_resolver_enable_vanitypath();
    }

    public boolean isOptimizeAliasResolutionEnabled() {
        return this.config.resource_resolver_optimize_alias_resolution();
    }

    public boolean isLogUnclosedResourceResolvers() {
        return this.config.resource_resolver_log_unclosed();
    }

    public String[] getVanityPathWhiteList() {
        return this.vanityPathWhiteList;
    }

    public String[] getVanityPathBlackList() {
        return this.vanityPathBlackList;
    }

    public boolean hasVanityPathPrecedence() {
        return this.config.resource_resolver_vanity_precedence();
    }

    public long getMaxCachedVanityPathEntries() {
        return this.config.resource_resolver_vanitypath_maxEntries();
    }

    public boolean isMaxCachedVanityPathEntriesStartup() {
        return this.config.resource_resolver_vanitypath_maxEntries_startup();
    }

    public int getVanityBloomFilterMaxBytes() {
        return this.config.resource_resolver_vanitypath_bloomfilter_maxBytes();
    }

    public boolean shouldLogResourceResolverClosing() {
        return this.config.resource_resolver_log_closing();
    }

    public Path[] getObservationPaths() {
        return this.observationPaths;
    }

    // ---------- SCR Integration ---------------------------------------------

    /**
     * Activates this component (called by SCR before)
     */
    @Activate
    protected void activate(final BundleContext bundleContext, final ResourceResolverFactoryConfig config) {
        this.bundleContext = bundleContext;
        this.config = config;

        final BidiMap virtuals = new TreeBidiMap();
        for (int i = 0; config.resource_resolver_virtual() != null && i < config.resource_resolver_virtual().length; i++) {
            final String[] parts = Mapping.split(config.resource_resolver_virtual()[i]);
            virtuals.put(parts[0], parts[2]);
        }
        virtualURLMap = virtuals;

        final List<Mapping> maps = new ArrayList<>();
        for (int i = 0; config.resource_resolver_mapping() != null && i < config.resource_resolver_mapping().length; i++) {
            maps.add(new Mapping(config.resource_resolver_mapping()[i]));
        }
        final Mapping[] tmp = maps.toArray(new Mapping[maps.size()]);

        // check whether direct mappings are allowed
        if (config.resource_resolver_allowDirect()) {
            final Mapping[] tmp2 = new Mapping[tmp.length + 1];
            tmp2[0] = Mapping.DIRECT;
            System.arraycopy(tmp, 0, tmp2, 1, tmp.length);
            mappings = tmp2;
        } else {
            mappings = tmp;
        }

        // from configuration if available
        final List<String> searchPathList = new ArrayList<>();
        if (config.resource_resolver_searchpath() != null && config.resource_resolver_searchpath().length > 0) {
            for(String path : config.resource_resolver_searchpath()) {
                // ensure leading slash
                if (!path.startsWith("/")) {
                    path = "/".concat(path);
                }
                // ensure trailing slash
                if (!path.endsWith("/")) {
                    path = path.concat("/");
                }
                searchPathList.add(path);
            }
        }
        if (searchPathList.isEmpty()) {
            searchPathList.add("/");
        }
        this.searchPath = Collections.unmodifiableList(searchPathList);

        // the root of the resolver mappings
        mapRoot = config.resource_resolver_map_location();
        mapRootPrefix = mapRoot + '/';

        final String[] paths = config.resource_resolver_map_observation();
        this.observationPaths = new Path[paths.length];
        for(int i=0;i<paths.length;i++) {
            this.observationPaths[i] = new Path(paths[i]);
        }

        // vanity path white list
        this.vanityPathWhiteList = null;
        String[] vanityPathPrefixes = config.resource_resolver_vanitypath_whitelist();
        if ( vanityPathPrefixes != null ) {
            final List<String> prefixList = new ArrayList<>();
            for(final String value : vanityPathPrefixes) {
                if ( value.trim().length() > 0 ) {
                    if ( value.trim().endsWith("/") ) {
                        prefixList.add(value.trim());
                    } else {
                        prefixList.add(value.trim() + "/");
                    }
                }
            }
            if ( prefixList.size() > 0 ) {
                this.vanityPathWhiteList = prefixList.toArray(new String[prefixList.size()]);
            }
        }
        // vanity path black list
        this.vanityPathBlackList = null;
        vanityPathPrefixes = config.resource_resolver_vanitypath_blacklist();
        if ( vanityPathPrefixes != null ) {
            final List<String> prefixList = new ArrayList<>();
            for(final String value : vanityPathPrefixes) {
                if ( value.trim().length() > 0 ) {
                    if ( value.trim().endsWith("/") ) {
                        prefixList.add(value.trim());
                    } else {
                        prefixList.add(value.trim() + "/");
                    }
                }
            }
            if ( prefixList.size() > 0 ) {
                this.vanityPathBlackList = prefixList.toArray(new String[prefixList.size()]);
            }
        }

        // check for required property
        Set<String> requiredResourceProvidersLegacy = getStringSet(config.resource_resolver_required_providers());
        Set<String> requiredResourceProviderNames = getStringSet(config.resource_resolver_required_providernames());

        boolean hasLegacyRequiredProvider = false;
        if ( requiredResourceProvidersLegacy != null ) {
            hasLegacyRequiredProvider = requiredResourceProvidersLegacy.remove(ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID);
            if ( !requiredResourceProvidersLegacy.isEmpty() ) {
                logger.error("ResourceResolverFactory is using deprecated required providers configuration (resource.resolver.required.providers" +
                        "). Please change to use the property resource.resolver.required.providernames for values: " + requiredResourceProvidersLegacy);
            } else {
            	requiredResourceProvidersLegacy = null;
            }
        }
        if ( hasLegacyRequiredProvider ) {
            final boolean hasRequiredProvider;
        	if ( requiredResourceProviderNames != null ) {
        		hasRequiredProvider = !requiredResourceProviderNames.add(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
        	} else {
        		hasRequiredProvider = false;
        		requiredResourceProviderNames = Collections.singleton(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
        	}
        	if ( hasRequiredProvider ) {
                logger.warn("ResourceResolverFactory is using deprecated required providers configuration (resource.resolver.required.providers" +
                        ") with value '" + ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID + ". Please remove this configuration property. " +
                        ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME + " is already contained in the property resource.resolver.required.providernames.");
        	} else {
                logger.warn("ResourceResolverFactory is using deprecated required providers configuration (resource.resolver.required.providers" +
                        ") with value '" + ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID + ". Please remove this configuration property and add " +
                        ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME + " to the property resource.resolver.required.providernames.");
        	}
        }

        // for testing: if we run unit test, both trackers are set from the outside
        if ( this.resourceProviderTracker == null ) {
            this.resourceProviderTracker = new ResourceProviderTracker();
            this.changeListenerWhiteboard = new ResourceChangeListenerWhiteboard();
            this.preconds.activate(this.bundleContext,
            		requiredResourceProvidersLegacy,
            		requiredResourceProviderNames,
            		resourceProviderTracker);
            this.changeListenerWhiteboard.activate(this.bundleContext,
                this.resourceProviderTracker, searchPath);
            this.resourceProviderTracker.activate(this.bundleContext,
                    this.eventAdmin,
                    new ChangeListener() {

                        @Override
                        public void providerAdded() {
                            if ( factoryRegistration == null ) {
                                checkFactoryPreconditions(null, null);
                            }

                        }

                        @Override
                        public void providerRemoved(final String name, final String pid, final boolean stateful, final boolean isUsed) {
                            if ( factoryRegistration != null ) {
                                if ( isUsed && (stateful || config.resource_resolver_providerhandling_paranoid()) ) {
                                    unregisterFactory();
                                }
                                checkFactoryPreconditions(name, pid);
                            }
                        }
                    });
        } else {
            this.preconds.activate(this.bundleContext,
            		requiredResourceProvidersLegacy,
            		requiredResourceProviderNames,
            		resourceProviderTracker);
            this.checkFactoryPreconditions(null, null);
         }
    }

    /**
     * Modifies this component (called by SCR to update this component)
     */
    @Modified
    protected void modified(final BundleContext bundleContext, final ResourceResolverFactoryConfig config) {
        this.deactivate();
        this.activate(bundleContext, config);
    }

    /**
     * Deactivates this component (called by SCR to take out of service)
     */
    @Deactivate
    protected void deactivate() {
        this.unregisterFactory();

        this.bundleContext = null;
        this.config = DEFAULT_CONFIG;
        this.changeListenerWhiteboard.deactivate();
        this.changeListenerWhiteboard = null;
        this.resourceProviderTracker.deactivate();
        this.resourceProviderTracker = null;

        this.preconds.deactivate();
        this.resourceDecoratorTracker.close();

        // this is just a sanity call to make sure that unregister
        // in the case that a registration happened again
        // while deactivation
        this.unregisterFactory();
    }

    /**
     * Unregister the factory (if registered)
     * This method might be called concurrently from deactivate and the
     * background thread, therefore we need to synchronize.
     */
    private void unregisterFactory() {
        FactoryRegistration local = null;
        synchronized ( this ) {
            if ( this.factoryRegistration != null ) {
                local = this.factoryRegistration;
                this.factoryRegistration = null;
            }
        }
        this.unregisterFactory(local);
    }

    /**
     * Unregister the provided factory
     */
    private void unregisterFactory(final FactoryRegistration local) {
        if ( local != null ) {
            if ( local.factoryRegistration != null ) {
                local.factoryRegistration.unregister();
            }
            if ( local.runtimeRegistration != null ) {
                local.runtimeRegistration.unregister();
            }
            if ( local.commonFactory != null ) {
                local.commonFactory.deactivate();
            }
        }
    }

    /**
     * Try to register the factory.
     */
    private void registerFactory(final BundleContext localContext) {
        final FactoryRegistration local = new FactoryRegistration();

        if ( localContext != null ) {
            // activate and register factory
            final Dictionary<String, Object> serviceProps = new Hashtable<>();
            serviceProps.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
            serviceProps.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Resource Resolver Factory");

            local.commonFactory = new CommonResourceResolverFactoryImpl(this);
            local.commonFactory.activate(localContext);
            local.factoryRegistration = localContext.registerService(
                ResourceResolverFactory.class, new ServiceFactory<ResourceResolverFactory>() {

                    @Override
                    public ResourceResolverFactory getService(final Bundle bundle, final ServiceRegistration<ResourceResolverFactory> registration) {
                        if ( ResourceResolverFactoryActivator.this.bundleContext == null ) {
                            return null;
                        }
                        final ResourceResolverFactoryImpl r = new ResourceResolverFactoryImpl(
                                local.commonFactory, bundle,
                            ResourceResolverFactoryActivator.this.serviceUserMapper);
                        return r;
                    }

                    @Override
                    public void ungetService(final Bundle bundle, final ServiceRegistration<ResourceResolverFactory> registration, final ResourceResolverFactory service) {
                        // nothing to do
                    }
                }, serviceProps);

            local.runtimeRegistration = localContext.registerService(RuntimeService.class,
                    this.getRuntimeService(), null);

            this.factoryRegistration = local;
        }
    }

    /**
     * Get the runtime service
     * @return The runtime service
     */
    public RuntimeService getRuntimeService() {
        return new RuntimeServiceImpl(this.resourceProviderTracker);
    }

    public ServiceUserMapper getServiceUserMapper() {
    	return this.serviceUserMapper;
    }

    public BundleContext getBundleContext() {
    	return this.bundleContext;
    }

    /**
     * Check the preconditions and if it changed, either register factory or unregister
     */
    private void checkFactoryPreconditions(final String unavailableName, final String unavailableServicePid) {
        final BundleContext localContext = this.bundleContext;
        if ( localContext != null ) {
            final boolean result = this.preconds.checkPreconditions(unavailableName, unavailableServicePid);
            if ( result && this.factoryRegistration == null ) {
                // check system bundle state - if stopping, don't register new factory
                final Bundle systemBundle = localContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
                if ( systemBundle != null && systemBundle.getState() != Bundle.STOPPING ) {
                    boolean create = true;
                    synchronized ( this ) {
                        if ( this.factoryRegistration == null ) {
                            this.factoryRegistration = new FactoryRegistration();
                        } else {
                            create = false;
                        }
                    }
                    if ( create ) {
                        this.registerFactory(localContext);
                    }
                }
            } else if ( !result && this.factoryRegistration != null ) {
                this.unregisterFactory();
            }
        }
    }

    /**
     * Bind a resource decorator.
     */
    @Reference(service = ResourceDecorator.class, cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
    protected void bindResourceDecorator(final ResourceDecorator decorator, final Map<String, Object> props) {
        this.resourceDecoratorTracker.bindResourceDecorator(decorator, props);
    }

    /**
     * Unbind a resource decorator.
     */
    protected void unbindResourceDecorator(final ResourceDecorator decorator, final Map<String, Object> props) {
        this.resourceDecoratorTracker.unbindResourceDecorator(decorator, props);
    }

    /**
     * Get the resource provider tracker
     * @return The tracker
     */
    public ResourceProviderTracker getResourceProviderTracker() {
        return resourceProviderTracker;
    }

    /**
     * Utility method to create a set out of a string array
     */
    private Set<String> getStringSet(final String[] values) {
    	if ( values == null || values.length == 0 ) {
    		return null;
    	}
    	final Set<String> set = new HashSet<>();
    	for(final String val : values) {
    		if ( val != null && !val.trim().isEmpty() ) {
    			set.add(val.trim());
    		}
    	}
    	return set.isEmpty() ? null : set;
    }

    public static ResourceResolverFactoryConfig DEFAULT_CONFIG;

    static {
       final InvocationHandler handler = new InvocationHandler() {

            @Override
            public Object invoke(final Object obj, final Method calledMethod, final Object[] args)
            throws Throwable {
                if ( calledMethod.getDeclaringClass().isAssignableFrom(ResourceResolverFactoryConfig.class) ) {
                   return calledMethod.getDefaultValue();
                }
                if ( calledMethod.getDeclaringClass() == Object.class ) {
                    if ( calledMethod.getName().equals("toString") && (args == null || args.length == 0) ) {
                        return "Generated @" + ResourceResolverFactoryConfig.class.getName() + " instance";
                    }
                    if ( calledMethod.getName().equals("hashCode") && (args == null || args.length == 0) ) {
                        return this.hashCode();
                    }
                    if ( calledMethod.getName().equals("equals") && args != null && args.length == 1 ) {
                        return Boolean.FALSE;
                    }
                }
                throw new InternalError("unexpected method dispatched: " + calledMethod);
            }
        };
        DEFAULT_CONFIG = (ResourceResolverFactoryConfig) Proxy.newProxyInstance(ResourceResolverFactoryConfig.class.getClassLoader(),
                new Class[] { ResourceResolverFactoryConfig.class },
                handler);
    }
}
